pthread条件和进程终止

Yev*_*y P 6 c unix multithreading ipc pthreads

我有一个进程共享的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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

首先运行p1,然后运行p2,在它说"在pthread_cond_wait之前"之后,按Ctrl-C它.然后在p1的shell中按Enter键.

起初,我无法重现挂起,但我同时使用pthread_cond_destroy()和pthread_mutex_destroy()来返回EBUSY.

但是现在如果我们在pthread_cond_destroy()之前调用pthread_cond_signal(),则挂起会重现(请参阅上面的代码).

小智 2

看起来 p2 进程永远在等待条件变量,因为 p1 进程没有机会发送被 ctrl-c 终止的通知。正如您和其他人已经提到的那样,pthread 条件变量并不“知道”其原始进程终止。

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