繁体   English   中英

带线程的Linux套接字文件描述符

[英]Linux Socket file descriptor with threads

考虑以下情况:一个线程(称为A)进行初始化,使用listen()设置套接字状态,然后使用accept()等待。 连接到达一个套接字, accept()返回有效的fd。 创建新线程(B)(使用std::thread ),并将获取的fd传递给线程B中运行的可调用对象。读取(使用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 READ\n"<<"ERRNO: "<<errno<<"\n"<<"FD: "<<socket_fd<<"\n";
    }
    return buffer;
}

DisplayMsgFun::DisplayMsgFun(char* buffer, int socket) :
    BaseFun(buffer, socket)
{}

void DisplayMsgFunFun::operator()()
{
    std::cout<<"Message:\n\t"<<buffer_read()<<"\nEND\n";
}

上面的代码段称为:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM