我正在开发一个聊天服务器,我有一个问题.
如何std::thread安全停车?
像这样很容易出问题.
thread t(&func);
t.join();
Run Code Online (Sandbox Code Playgroud)
但是,如果func具有无限循环,则连接不起作用.
这是我的来源.
void CServerSocket::AcceptRun(boost::asio::io_service &iosrv)
{
while (true)
{
auto sock = std::make_shared<boost::asio::ip::tcp::socket>(iosrv);
m_Acceptor->accept(*sock);
m_SocketList.push_back(std::make_shared<CConnectionSocket>(this, sock));
}
}
Run Code Online (Sandbox Code Playgroud)
和
CServerSocket::~CServerSocket()
{
CLogManager::WriteLog("Stopping Server...");
m_Acceptor->close();
m_Acceptor.reset();
// m_AcceptThread.detach(); This is right?
CLogManager::WriteLog("Server Stoped!");
}
Run Code Online (Sandbox Code Playgroud)
我很纳闷.请帮我.谢谢.
我有一个用C编写的多线程服务器,每个客户端线程看起来像这样:
ssize_t n;
struct request request;
// Main loop: receive requests from the client and send responses.
while(running && (n = recv(sockfd, &request, sizeof(request), 0)) == sizeof(request)) {
// Process request and send response.
}
if(n == -1)
perror("Error receiving request from client");
else if(n != sizeof(act))
fprintf(stderr, "Error receiving request from client: Incomplete data\n");
// Clean-up code.
Run Code Online (Sandbox Code Playgroud)
在某些时候,客户满足必须断开连接的特定标准.如果客户端定期发送请求,这很好,因为可以通知响应中的断开连接; 但是,有时客户端需要很长时间才能发送请求,因此客户端线程最终会在recv调用中阻塞,并且客户端在下一个请求/响应之前不会断开连接.
当客户端线程在recv呼叫中阻塞时,是否有一种干净的方法来断开客户端与另一个线程的连接?我试过,close(sockfd)但这会导致错误Error receiving request from client: Bad file descriptor发生,这实际上是不准确的.
或者,我有更好的方法来处理错误吗?
我有一个简单的客户端/服务器应用程序,其代码如下所述。请在 Linux 中的一个 shell 中运行服务器,在另一个 shell 中运行客户端。首先启动服务器,然后启动客户端。当服务器完成工作后,它会崩溃并出现以下异常:
抛出“std::system_error”实例后终止调用what():避免资源死锁
这是从函数 Service::HandleClient 内部的 m_thread->join() 行发生的,我不知道发生了什么。有人可以检查一下代码吗?我只是希望服务器应用程序也应该正确关闭客户端应用程序关闭的方式。
**服务器代码:**
#include <boost/asio.hpp>
#include <thread>
#include <atomic>
#include <memory>
#include <iostream>
using namespace boost;
class Service {
public:
Service(){}
void StartHandligClient(
std::shared_ptr<asio::ip::tcp::socket> sock) {
m_thread.reset(new std::thread (([this, sock]() {
HandleClient(sock);
})) );
}
private:
void HandleClient(std::shared_ptr<asio::ip::tcp::socket> sock) {
while(1)
{
try {
asio::streambuf request;
std::cout << "Waiting to read \n";
asio::read_until(*sock.get(), request, '\n');
std::string s( (std::istreambuf_iterator<char>(&request)), std::istreambuf_iterator<char>() );
std::cout << "Server got : " << s << …Run Code Online (Sandbox Code Playgroud) 在做socket编程的时候,用多线程,
如果线程在 Accept 函数上被阻塞,
并且主线程试图关闭进程,
如何中断接受函数以安全地 pthread_join?
我对如何通过将自身连接到自己的端口以破坏接受功能来执行此操作有模糊的记忆。
任何解决方案将不胜感激。
干杯
我有一个侦听新连接的线程
new_fd = accept(Listen_fd, (struct sockaddr *) & their_addr, &sin_size);
Run Code Online (Sandbox Code Playgroud)
和另一个在关闭程序时关闭Listen_fd的线程.然而,在Listen_fd关闭后,它仍然会阻塞.当我使用GDB尝试和调试时,accept()不会阻塞.我认为这可能是SO_LINGER的问题,但默认情况下它不应该打开,并且在使用GDB时不应该更改.有什么想法,或关闭列表套接字的任何其他建议?
是否存在OS便携式中断阻塞的方法accept?我有一个多线程守护进程/服务,当deamon/service获得关闭信号时,需要正常关闭所有侦听网络主机.我看到有人说你应该使用非阻塞套接字或选择超时 - 但这些会不会降低性能,因为我的应用程序应尽可能快?守护进程在主线程中运行,而每个侦听网络主机都在自己的线程中运行.现在的问题是,accept如果侦听网络主机的套接字上没有网络流量,则无限期地等待.如果我应该使用信号,那么有一个使用信号中断的例子accept吗?