C 多线程程序中选择互斥锁和解锁位置的策略
在下面的代码片段中,我需要保护connfd,因为它可以在C 多线程程序中选择互斥锁和解锁位置的策略,c,multithreading,mutex,C,Multithreading,Mutex,在下面的代码片段中,我需要保护connfd,因为它可以在accept()call中频繁更改 void *deal_conn(void *arg){ int connfd; connfd = *((int*)arg); .... } for(;;){ connfd = accept(...); pthread_create(&thread, NULL, deal_conn, &connfd); }
accept()
call中频繁更改
void *deal_conn(void *arg){
int connfd;
connfd = *((int*)arg);
....
}
for(;;){
connfd = accept(...);
pthread_create(&thread, NULL, deal_conn, &connfd);
}
我不知道该在哪里锁定和解锁此变量的互斥锁。
有人能给我一些想法吗?
谢谢 不要将
connfd
的地址传递给每个线程,动态分配一个新的int
并传递该地址,当不再需要时,让线程空闲()。由于线程不再共享同一资源,因此不需要互斥:
connfd = accept(...);
if (connfd != -1)
{
int* fd = malloc(sizeof(*fd));
if (fd)
{
*fd = connfd;
pthread_create(&thread, NULL, deal_conn, fd);
}
}
void *deal_conn(void *arg){
int connfd = *((int*)arg);
free(arg);
}
除此之外,我更喜欢使用其他人提出的动态分配套接字描述符变量的解决方案,以下是对OP问题的回答:
void *deal_conn(void * arg)
{
int connfd = *((int *) arg);
/* unlock mutex here */
...
}
...
/* init mutex here */
for(;;)
{
/* lock mutex here */
int connfd = accept(...);
if (-1 == connfd)
{
/* in case of error unlock mutex here, as the deal_conn() will not be called */
}
else
{
int result = pthread_create(..., deal_conn, &connfd);
if (-1 == result)
{
/* in case of error unlock mutex here, as the deal_conn() will not be called */
}
}
...
如何更改代码,如下所示:
void *deal_conn(void *arg){
int connfd;
connfd = (int)arg;
....
}
for(;;){
connfd = accept(...);
pthread_create(&thread, NULL, deal_conn, (void *)connfd);
}
我看不出有必要锁定connfd,connfd被复制到新线程的堆栈中,而不是由线程共享。connfd作为指针传递-在deal\u conn函数期间,该值可能会更改。考虑使用MT安全MAOLC调用创建一个单独的安全的CONFD拷贝,传递给DealyCon函数。然后,deal\u conn可以释放该变量。是什么阻止您在调用accept()之前锁定
并在将套接字描述符分配给线程函数的本地变量后解锁?我认为pthread\u create可能会在deal\u conn
从&connfd获取值之前返回。@user1944267:这完全可以,因为在调用accept()之前,accept()循环将阻止锁定互斥锁的调用
只要互斥锁没有被deal\u conn解锁
。我认为上面的代码有问题,你认为是吗?@user1944267:你指的是什么?我认为hmjd
的代码有问题,在他的代码中,*fd的值永远不会改变,fd的值可能会在线程获得其值之前更改。不是吗?你这样认为吗?我认为还有问题。虽然*fd
的值永远不会改变,但是fd
的值可能会在线程获得其值之前改变。是吗?啊,你的意思是:即使在下一个accept()
返回后执行新线程,fd
的值已经复制到新线程的堆栈中了fd
是指向动态分配内存的指针。只有它被传递到的线程才能访问分配的内存。我不是指它指向的分配内存,我是指指针本身。是的,地址已经传递到新线程,所以下次使用fd不会影响它。哇,看起来很酷。因此,即使connfd是4字节,(void*)是8字节,强制转换仍然可以?使用intptr\u t
类型化变量传递给pthread\u create()
,因为它保证与void*
`(void*)(uint64\u t)connfd`的大小相同portable@alk,connfd是int类型,而不是intptr\t,我不明白你的评论,我忘了有一个uintptr_t(指针大小的uint)。这应该更好