0
請考慮以下情況:一個線程(讓我們稱之爲A)初始化,將套接字狀態設置爲listen()
,然後等待accept()
。連接到達A插座,accept()
返回有效的fd。創建新線程(B)(使用std::thread
),並將獲取的fd傳遞給在線程B中運行的可調用對象。使用read()
讀取fd失敗,並且errno
設置爲9 EBADFD
。線程A在B上調用join()
。當B未生成且使用fd(仍然通過相同的可調用對象)時,讀取完成而沒有失敗。爲什麼?下面是一些代碼來說明這種情況。Linux Socket文件描述符與線程
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;
}
與你的問題無關,但爲什麼創建一個線程,如果你接下來要做的只是等待它呢?我假設你在線程創建和'join'調用之間做了一些其他的事情?也許問題是*那部分(你沒有告訴我們)? –
我很想看看你如何解決這個問題。我知道足夠的C++來發現問題(根據我的答案),但不能解決它。我想知道是否只寫'std :: thread job(std :: ref(dm))'就足夠了。 – Alnitak
@Alnitak我運行了快速測試,'std :: ref()'解決了問題。但我想這在「大規模」中還不夠,或者我會試圖擺脫這種「join()」調用。 – Ufo