由於listen
函數有一個積壓,你可以設置,即。它將保持隊列中的所有連接,並且當調用accept
時,隊列中等待的第一個元素實際上被接受,這方面的解決方案如下。
在無限循環中,只要計數器小於特定數量(同時服務的最大客戶端數量),就只接受連接。 聲明一個mutex
,用於保護每次接受連接時遞增的計數器。 當一個線程完成他的任務時,聲明一個條件變量給b用於發信號。 使用該條件變量和一個互斥鎖,等待計數器大於X. 當服務於客戶端的線程完成其任務時,遞減計數器併發送條件。因此,無限循環將再次循環並接受一個已保留的客戶端。
一個可能實現的,這可能是:
// global variable
pthread_mutex_t lock;
pthread_cond_t cv;
int number_of_connected_client = 0;
// a function executed by a thread to handle each user
void *client_thread(void *arg) {
/* some code */
// thread is about to finish and return
// client disconnected --> decrement number of connected clients
// signal that a client disconnected
pthread_mutex_lock(&lock);
number_of_connected_client-- ;
pthread_cond_signal(&cv);
pthread_mutex_unlock(&lock);
return 0;
}
// infinte loop for accepting connections
while (1) {
// serve 2 users at a time, queue the rest of the clients in the listen's queue
if(number_of_connected_client >= 2) {
pthread_mutex_lock(&lock);
pthread_cond_wait(&cv, &lock);
pthread_mutex_unlock(&lock);
}
connfd = accept(listenfd, (struct sockaddr *) NULL, NULL);
// create a thread and serve the client
if(pthread_create(&thread_id , NULL , client_thread, (void*)connfd) <0)
{
// error in creating thread
// do something
}
// client is served --> increment number of connected clients
else {
pthread_mutex_lock(&lock);
number_of_connected_client ++;
pthread_mutex_unlock(&lock);
}
}
這只是一個簡單的解決辦法得到的東西私人測試或硬件或等..處理這個問題的正確方法工作是一個線程池工作者線程根據Inspired的評論提供了任務。
或者您可能需要3個工作線程,每個線程都讀取來自隊列的連接請求。 (一般來說,接受一個連接,然後保持它暫停可能不是從客戶的角度來看最好的經驗。) – Inspired
所以你的意思是我保持隊列中的所有連接,並有3個工作線程保持彈出和服務? 。哦,是的,我同意你的意見,但只是爲了練習。 –
正確。這只是您建議的方案的簡化(不再需要創建/加入線程,並且不需要計數器)。 – Inspired