2016-12-28 190 views
1

我創建了一個TCP客戶端應用程序,並決定使用c中的pthread庫使用新線程處理傳入數據。多線程寫入套接字

但是,我在某處發現,當多個線程嘗試寫入同一個套接字連接的文件描述符時,可能會發生意想不到的事情。

什麼是確保這些「意想不到的事情」不會發生的最佳方法。

是否還需要首先使用線程?

注意:我決定使用線程是爲了防止任何阻塞操作。

+1

最好的方法是確保只有一個線程讀取/寫入套接字。注意:在決定使用線程之前,你需要解釋爲什麼阻塞是不可取的。 – user3386109

+0

投票關閉:太寬 – Stargateur

+0

該應用程序是USSD應用程序 - 非結構化補充服務數據。它將服務多個用戶,有時幾乎在同一時間撥打短代碼。 USSD網關有效超時,並且要求客戶端應用程序在此時間範圍內提供響應。當用戶需要等待時,他們的請求可能會超時,用戶體驗將受到嚴重影響。 –

回答

1

爲避免阻塞,您應該研究異步操作。您可以瞭解您的特定平臺如何處理它們,或者使用庫(如ASIO(https://think-async.com/))來處理它。

-2
  • 是的,你需要創建線程,如果你想要做什麼都在等待進入的TCP數據

  • 是的,你需要照顧的,可能在多線程程序中發生意想不到的事情

您應該使用Mutexes來防止所謂的意外事件。您用於創建線程的pthread庫也包含同步基元。

的樣本程序可能看起來像這樣

pthread_mutex_t tcp_lock; 

void ThreadFunction() 
{ 
     pthread_mutex_lock(&tcp_lock); 
     // Do your stuffs 
     pthread_mutex_unlock(&tcp_lock); 
} 

int MainThread() 
{ 
    pthread_mutex_lock(&tcp_lock); 
    // Do your stuffs 
    pthread_mutex_unlock(&tcp_lock); 
} 
+2

「是的,如果您想在等待傳入的TCP數據時執行其他任何操作,則需要創建線程」,否。男人選擇,民意調查。他們有很多方法來做服務器,線程就是其中之一。 – Stargateur

+0

不,如果您在等待傳入的TCP數據時想做其他任何事情,則不需要創建線程。您可以使用非阻塞或多路複用或異步I/O。 – EJP

0

我可能會建議使用libuv?它高度維護(node.js的核心)和跨平臺。

此外,你不應該使用select()這是舊學校。如果你自己做了,你應該在Linux上使用epoll()。它規模更好。

你應該只有一個作家線程。該線程應該在套接字不忙時寫入。

結帳libuv - 它爲你處理所有這些混亂,但仍然讓你接近金屬。 https://nikhilm.github.io/uvbook/networking.html

我對這類東西的處理方式通常是有一個寫入程序線程和一個快速讀取程序回調,通常只是爲傳入數據分配內存,然後將其分配給一個或多個處理線程。如果你想快速避免memcpy不惜一切代價,並分配一個大緩衝區開始。