2017-01-09 11 views
0

以下の状況を考慮してください:1つのスレッド(Aと呼ぶことができます)が初期化し、ソケットの状態をlisten()に設定してからaccept()で待機します。接続はAソケットに到着し、accept()は有効なfdを返します。取得されたfdがスレッドBで実行可能な呼び出し可能オブジェクトに渡されます。fdの読み取り(read()を使用)が失敗し、errno9 EBADFDに設定されています。スレッドAはBにjoin()を呼び出します.Bが生成されず、fdが使用されている場合(同じ呼び出し可能オブジェクト経由でも)、読み取りは失敗せずに完了します。どうして?以下は、この状況を示すためのコードです。スレッドを持つLinuxソケットファイル記述子

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; 
} 
+0

あなたの問題とは無関係ですが、次に行うことがそれを待つだけの場合は、なぜスレッドを作成するのですか?スレッドの作成と 'join'呼び出しの間に何か他のことをしていると思いますか?たぶん、問題は*あなたが私たちを見せない部分ですか? –

+0

これをどのように修正するのか興味があります。私は問題を(私の答えごとに)見つけ出すのに十分なC++を知っていますが、それを修正することはできません。 'std :: thread job(std :: ref(dm))'を書くだけで十分だろうかと思います。 – Alnitak

+0

@Alnitak私はクイックテストを実行し、 'std :: ref()'は問題を解決します。しかし、私は "大規模"で十分ではないか、この 'join()'呼び出しを取り除こうとすると思います。 – Ufo

答えて

2

あなたがいることを意味しstd::threadコンストラクタにDisplayMsgFunオブジェクトのコピーを渡すように見えます元のコピーが破棄され、自動的に::closeトラクター。

関連する問題