我目前正在使用的應用程序是一個服務器,它將使用select()來管理與客戶端的連接,每次服務器收到消息時,它都會打開一個新線程以讀取套接字。在此期間,套接字的文件描述符將從該集中刪除,並將在讀取結束時添加。 下面是代碼的樣本是FD_SET,FD_CLR ...原子操作嗎?
struct s_handle {
int sock;
fd_set * rdfs;
};
int main(){
...
fd_set rdfs;
...
while(1){
....
select(nb_fd,&rdfs,NULL,NULL,NULL)
for_each(peer){
if(FD_ISSET(peer->sock,&rdfs)){
struct s_handle * h = malloc(sizeof(struct s_handle));
h->sock = peer->sock;
h->rdfs = &rdfs;
FD_CLR(peer->sock,&rdfs);
pthread_create(thread,NULL,handle,(void *)&h);
}
}
...
}
...
}
void* handle(void* argss){
struct s_handle * temp = (struct s_handle *) argss;
...
FD_SET(temp->sock,temp->rdfs);
}
不FD_SET,FD_ISSET和FD_CLR是原子操作,或者我需要用互斥鎖RDFS?
如果需要互斥鎖,我該如何避免死鎖?
如果你讓這個線程擁有自己的'fd_set'並且調用'select'本身,那麼這個線程必須呆在等待I/O。然後,在該特定線程安排之前,無法在該套接字上完成任何工作。所以你會消耗大量額外的資源,所有這些線程都會等待,並且需要大量額外的上下文切換來獲得正確的線程運行。 (但是,考慮到他使用'select',他可能不關心性能。) – 2012-02-26 22:15:52
我寫這些時有點困惑 - 它沒有完全點擊它產生一個線程來讀取,然後退出而不放棄。我正在考慮創建一個線程來讀取套接字,並保持這個套接字直到連接關閉 - 儘管看起來不像他正在做的那樣。 – Dmitri 2012-02-26 22:41:21