带有线程的 Linux 套接字文件描述符
Linux Socket file descriptor with threads
考虑以下情况:一个线程(我们称之为A)初始化,使用listen()
设置套接字状态,然后等待accept()
。连接到达 A 套接字,accept()
返回有效的 fd。创建新线程 (B)(使用 std::thread
),并将获取的 fd 传递给线程 B 中运行的可调用对象 witch.读取(使用 read()
)fd 失败,errno
设置为 9 EBADFD
。线程 A 在 B 上调用join()
。当 B 未生成且使用 fd 时(仍然通过相同的可调用对象),读取完成且不会失败。为什么?下面是一些代码来说明这种情况。
BaseFun::BaseFun(char* bufferAdr, int socket):
socket_fd(socket)
buffer(bufferAdr)
{}
BaseFun::~BaseFun()
{
close(socket_fd);
}
char* BaseFun::buffer_read()
{
if(read(socket_fd, buffer, BUFF_SIZE-1) < 0) {
std::cout<<"ERROR while READn"<<"ERRNO: "<<errno<<"n"<<"FD: "<<socket_fd<<"n";
}
return buffer;
}
DisplayMsgFun::DisplayMsgFun(char* buffer, int socket) :
BaseFun(buffer, socket)
{}
void DisplayMsgFunFun::operator()()
{
std::cout<<"Message:nt"<<buffer_read()<<"nENDn";
}
上面调用的代码段:
void Server::server_run()
{
sockaddr_in client_addr;
socklen_t c_len = sizeof(client_addr);
client_fd = accept(sock_fd, (sockaddr*)&client_addr, &c_len);
DisplayMsgFun dm(server_buffers->front().data(), client_fd);
std::thread job(dm);
job.join();
}
和main()
int main()
{
Server srv(PORT);
if (srv.server_create()) {
std::cout << "Server bind!n";
srv.server_run();
}
else {
std::cout << "Bind fail! ERRNO: "<<errno<<"n";
return -1;
}
return 0;
}
您似乎正在将DisplayMsgFun
对象的副本传递给std::thread
构造函数,这意味着原始副本将被销毁,并根据您的析构函数自动调用::close
。
相关文章:
- 使用VerQueryValue检索应用程序的文件描述
- 如何在C/C++中用FD_set Unix设置套接字文件描述符
- I2C 文件描述符上的 I2C 总线可写/可读标志
- 许多文件描述符在调用sys_clone时
- AMQP-CPP >处理程序中的错误文件描述符
- 如何使用 WINAPI 和 C++ 提取可执行文件的文件描述?
- 正在等待在非阻塞文件描述符上长时间运行ioctl
- 有没有适用于Windows.lib文件的GNU二进制文件描述符(BFD)
- 如何强制文件描述符缓冲我的输出
- 如何从 boost::asio::ssl::stream<boost::asio::ip::tcp::socket> 获取本机套接字文件描述器?
- 哪个更适合从C++写入敏感的日志文件,在文件描述符上写()或文件上的fprintf()?
- 将 select() 与非基于文件描述符的输入一起使用
- accept(..) 似乎正在修改我给它的文件描述符参数
- 使用 Select 多路复用未命名的管道和其他文件描述符
- 提升 ASIO 绑定:错误的文件描述符
- 使用文件描述符移动对象
- 无法从零MQ ZMQ_SERVER套接字中获取文件描述符
- read() 上的不同行为取决于写入不可写内存时表示文件、匿名管道或套接字的文件描述符
- 我可以在不使用 FIOCANCEL 的情况下关闭 VxWorks 中的文件描述符吗?
- 将 Boost Asio 与 ZeroMQ 集成,文件描述符错误?