2012-04-16 113 views
1

我有一個關於一行爲我不太明白問題:C++傳遞對象給一個線程

我有C++代碼兩個變化:

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) clientThread, (LPVOID) connectionSocket, 0, NULL); 

螺紋:

Client a; 
a.clientsocket = connectionSocket; 
a.testText() 
a.sendSocket(); 

工作得很好(sendSocket發送一些測試數據到套接字)。

但是,如果我這樣做

Client a; 
a.clientsocket = connectionSocket; 
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) clientThread, (LPVOID) &a, 0, NULL); 

,並使用 螺紋:

a.testText(); 
a.sendSocket(); 

僅testText()的作品。

我有點困惑,這是爲什麼。我對C++的一個業餘愛好者,雖然:-)

編輯:

添加客戶端類:

class Client 
{ 
public: 
    SOCKET clientsocket; 

    Client() 
{ 
} 
~Client(){} 
void displayMessage() 
{ 
     std::cout << "test message client class" << std::endl; 
} 
int sendSocket() 
{ 
    char *sendbuf = "CLIENT TEST"; 
    send(clientsocket, sendbuf, (int)strlen(sendbuf),0); 
    closesocket(clientsocket); 
    return 0; 

} 
}; 
+0

當你第二次調用'a.sendSocket()'時會發生什麼?有某種例外或某種東西?應用程序崩潰了嗎? – Kiril 2012-04-16 18:24:24

+0

no不會崩潰,它只是不會向connectionSocket發送數據。 a.clientsSocket – user912877 2012-04-16 18:44:28

+0

調試器中的'a.clientSocket'看起來如何?它仍然有效嗎? – Kiril 2012-04-16 18:46:51

回答

0

匿名 可能是在正確的軌道上的東西超出範圍,但我認爲這是connectionSocket。然而,當你說a.sendSocket()不起作用時,你將不得不提供更多的細節。應用程序崩潰了嗎?你有沒有發現異常?應用程序是否繼續工作,但sendSocket()調用並未導致實際發送內容? 實際問題是什麼?

+0

應用程序不會崩潰,sendSocket()會在connectionSocket上發送文本消息。在第一個版本中,它確實發送了它,而在第二個版本中則沒有。我想要做的是將一個對象傳遞給一個線程,包括套接字作爲對象的公共變量。這樣做的原因是我可以實例化並訪問線程外部的對象。 – user912877 2012-04-16 18:37:46

+0

它看起來像'connectionSocket'是一個指向實際套接字的指針,所以我建議您在將它傳遞給線程後驗證它沒有被銷燬。你必須確保套接字的生命期足夠長,以便線程可以使用它。 – Kiril 2012-04-16 18:40:56

+0

「實際問題」是,除非我在線程中實例化對象,我顯然不能寫入a.clientsocket。我想實例化線程外的對象。它不會發送任何東西(我可以在客戶端看到) – user912877 2012-04-16 18:50:22

2

我猜,在你的主線程中的CreateThread成功,然後再你的客戶端變量,一個,超出了範圍,因此被破壞。

+0

我認爲他的'connectionSocket'超出了範圍。如果它是客戶端,那麼'a.testText()'不起作用。 – Kiril 2012-04-16 18:23:33

+0

我正在傳遞&a通過CreateThread()和a.testText()在線程中工作。那麼它是如何超出範圍的? – user912877 2012-04-16 18:24:57

+0

a.sendSocket()使用a.clientsocket ...不應該被保存在對象中? – user912877 2012-04-16 18:26:12

0

在第一種情況下,您傳遞一個connectionSocket,在第二種情況下,指向一個是Client類型的指針。也許你的意思是:

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) clientThread, (LPVOID) a.clientsocket, 0, NULL); 
0

在我看來,它是一個超出範圍的對象。 SOCKET只是一個int HANDLE值並存儲在一個成員中。當創建線程運行時,'a'在線程創建函數中超出範圍,(或者在下一個accept()返回時損壞)。

Try:

Client a = new Client();

在分配多線程代碼中的堆棧中的對象之前,請考慮15次,然後決定動態分配。

PS - @Anon先到那裏 - 我沒有注意到。

0

從客戶端類

SOCKET clientsocket; 

只要你傳遞上到一個線程,則SOCKET將不得不調用它的拷貝構造函數。這個拷貝構造函數可能是未定義的,或者它可能試圖在同一個端口上打開一個新的連接並導致它失敗。

它改成這樣:

SOCKET* clientsocket; 

那麼它的話,只要你想做的事......

a.clientsocket = connectionSocket; 

變量「connectionSocket」是一個指針,然後熱潮而來的炸藥。當它沒有被聲明爲一個變量時,拷貝構造函數被調用,並且你得到一個全新的套接字,而不是你之前使用的套接字。我認爲這應該有所幫助?