我目前正在使用的应用程序是一个服务器,它将使用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