Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C pthread条件和进程终止_C_Multithreading_Unix_Pthreads_Ipc - Fatal编程技术网

C pthread条件和进程终止

C pthread条件和进程终止,c,multithreading,unix,pthreads,ipc,C,Multithreading,Unix,Pthreads,Ipc,我有一个进程共享的pthread条件(带有关联的互斥)。如果在此条件下等待的进程(使用pthread_cond_wait()或pthread_cond_timedwait())被终止,会发生什么情况?其他流程是否仍可以使用此条件 在我的场景流程中,1等待条件并被终止。进程#2在某个时刻看到它是唯一一个现在使用该条件的进程,并调用pthread_cond_destroy() 我看到的是pthread_cond_destroy()只是挂起。有人遇到过同样的问题吗 从pthread_cond_dest

我有一个进程共享的pthread条件(带有关联的互斥)。如果在此条件下等待的进程(使用pthread_cond_wait()或pthread_cond_timedwait())被终止,会发生什么情况?其他流程是否仍可以使用此条件

在我的场景流程中,1等待条件并被终止。进程#2在某个时刻看到它是唯一一个现在使用该条件的进程,并调用pthread_cond_destroy()

我看到的是pthread_cond_destroy()只是挂起。有人遇到过同样的问题吗

从pthread_cond_destroy()的手册页可以看出,破坏某些线程仍在等待的条件会导致未定义的行为。在我的例子中,当进程#2调用pthread_cond_destroy()时,没有人再等待了,因为等待的进程#1已终止,但显然条件本身仍然认为存在等待的线程

有办法解决这个问题吗

编辑:

根据请求,我发布了示例程序(我在这里颠倒了p1和p2):

p1.cpp:

#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

struct MyCond {
    pthread_mutex_t m;
    pthread_cond_t c;
};

int main()
{
    pthread_mutexattr_t ma;
pthread_mutexattr_init(&ma);
pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED);

pthread_condattr_t ca;
pthread_condattr_init(&ca);
pthread_condattr_setpshared(&ca, PTHREAD_PROCESS_SHARED);

int fd = shm_open("/test_cond_p", O_RDWR|O_CREAT, 0666);
ftruncate(fd, sizeof(MyCond));

MyCond *c = (MyCond *)mmap(NULL, sizeof(MyCond),
    PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);
//close (fd);

pthread_mutex_init(&c->m, &ma);
pthread_cond_init(&c->c, &ca);
printf("Inited MyCond, %x\n", c);

puts("Press Enter to continue");
fgetc(stdin);

    int r = pthread_cond_signal(&c->c);
    printf("After pthread_cond_signal, r=%d\n", r);

puts("Before pthread_cond_destroy");
r = pthread_cond_destroy(&c->c);
printf("After pthread_cond_destroy, r=%d\n", r);
r = pthread_mutex_destroy(&c->m);
printf("After pthread_mutex_destroy, r=%d\n", r);

munmap(c, sizeof(MyCond));
shm_unlink("/test_cond_p");

return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
结构MyCond{
pthread_mutex_t m;
pthread_cond_t c;
};
int main()
{
pthread_mutexttr_ma;
pthread_mutexattr_init(&ma);
pthread_mutexattr_setpshared(&ma,pthread_PROCESS_SHARED);
pthread_condattr_t ca;
pthread_condattr_init(&ca);
pthread_condattr_setpshared(&ca,pthread_PROCESS_SHARED);
int fd=shm_open(“/test_cond_p”,O_RDWR | O_CREAT,0666);
ftruncate(fd,sizeof(MyCond));
MyCond*c=(MyCond*)mmap(NULL,sizeof(MyCond),
保护读写,映射共享,fd,0);
//关闭(fd);
pthread_mutex_init(&c->m,&ma);
pthread_cond_init(&c->c和&ca);
printf(“初始化MyCond,%x\n”,c);
puts(“按回车键继续”);
fgetc(stdin);
intr=pthread\u cond\u信号(&c->c);
printf(“在pthread\u cond\u信号之后,r=%d\n”,r);
puts(“在pthread_cond_destroy之前”);
r=pthread\u cond\u destroy(&c->c);
printf(“在pthread\u cond\u destroy之后,r=%d\n”,r);
r=pthread\u mutex\u destroy(&c->m);
printf(“在pthread\u mutex\u destroy之后,r=%d\n”,r);
munmap(c,sizeof(MyCond));
shm_解除链接(“/测试条件”);
返回0;
}
p2.cpp:

#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>

struct MyCond {
pthread_mutex_t m;
pthread_cond_t c;
};

int main()
{
int fd = shm_open("/test_cond_p", O_RDWR, 0666);

MyCond *c = (MyCond *)mmap(NULL, sizeof(MyCond),
    PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);
//close (fd);

pthread_mutex_lock(&c->m);
puts("Before pthread_cond_wait");
int r = pthread_cond_wait(&c->c, &c->m);
printf("After pthread_cond_wait, r=%d\n", r);

munmap(c, sizeof(MyCond));
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构MyCond{
pthread_mutex_t m;
pthread_cond_t c;
};
int main()
{
int fd=shm_打开(“/test_cond_p”,O_RDWR,0666);
MyCond*c=(MyCond*)mmap(NULL,sizeof(MyCond),
保护读写,映射共享,fd,0);
//关闭(fd);
pthread_mutex_lock(&c->m);
puts(“在pthread_cond_wait之前”);
intr=pthread\u cond\u wait(&c->c,&c->m);
printf(“在pthread\u cond\u wait之后,r=%d\n”,r);
munmap(c,sizeof(MyCond));
返回0;
}
首先运行p1,然后运行p2,在它说“在pthread_cond_wait之前”之后,按Ctrl-C键。然后在p1的外壳中按Enter键

起初,我无法复制挂起,但我让pthread_cond_destroy()和pthread_mutex_destroy()返回EBUSY


但是现在,如果我们在pthread_cond_destroy()之前调用pthread_cond_signal()(请参见上面的代码),则挂起会再次出现。

似乎p2进程一直在等待条件变量,因为p1进程没有机会发送由ctrl-c终止的通知。正如您和其他人已经提到的,pthread条件变量并不“知道”其原始进程终止


如果您不能使用其他进程间通信功能,并且仍然坚持使用共享互斥和条件变量,我会考虑捕获信号。

在调用pthread_cond_destroy()之前,还有一个选项可能是显式调用

像这样:

r = pthread_cond_broadcast(&c->c);
puts("Before pthread_cond_destroy");
r = pthread_cond_destroy(&c->c);
printf("After pthread_cond_destroy, r=%d\n", r);
r = pthread_mutex_destroy(&c->m);
printf("After pthread_mutex_destroy, r=%d\n", r);
的源代码说明如下:

因此,我们可以假设仍在访问condvar的所有服务员都已被唤醒。我们一直等到他们确认已经通过减少鹪鹩醒来

因此,我们可以在pthread_cond_destroy之前简单地将wrefs重置为零:

c->c.__data.__wrefs = 0;
r = pthread_cond_destroy(&c->c);
我用这个更改运行了您的示例,P1完成时没有挂起


请注意,在调用wrefs之前,waiters。

was terminated是否表示调用了pthread\u cancel?在这种情况下,应该启用清理处理程序。下面是用户定义的rwlock对象的POSIX示例,使用互斥锁。请看示例部分:显示一些代码。对Jim来说:不,我的意思是当整个过程通过一个信号终止时,让我们假设没有办法截获该信号来进行任何清理。对Pilcrow来说,代码中还有很多其他不相关的事情,所以整个代码很难在这里发布,但为了澄清这个场景:进程#2创建共享内存段来存储条件及其关联的互斥体,并对它们调用pthread_cond_init()和pthread_mutex_init()(启用pthread_process_shared属性)。然后它继续做其他事情。进程#1映射到所述共享内存段,获取指向条件和互斥变量的指针。然后它获取互斥体并调用pthread_cond_wait()等待条件。您是否建议永远不要调用pthread_cond_destroy和pthread_mutex_destroy?我不会泄露内存或其他资源?谢谢。是的,我想我需要使用不同的IPC通信方法。由于我正在编写一个库,为了避免干扰应用程序的信号处理,捕获信号可能不是一个好主意。