c语言 - 在等待时中断 pselect - 多线程



因此,根据手册,pselect可以有一个超时参数,如果没有文件描述符更改,它将等待。此外,它还可以选择被信号中断:

sigemptyset(&emptyset);    /* Signal mask to use during pselect() */
res = pselect(0, NULL, NULL, NULL, NULL, &emptyset);
if (errno == EINTR) printf("Interrupted by signaln");

然而,从手册中看不出哪些信号能够中断pselect?

如果我有线程(生产者和消费者),并且每个(消费者)线程都在使用 pselect,有没有办法只中断另一个(生产者)线程中的一个(消费者)线程?

我认为这个问题在https://lwn.net/Articles/176911/中进行了分析

出于这个原因,POSIX.1g委员会设计了一个增强版select(),叫pselect()select()pselect()是后一个调用具有信号掩码(sigset_t)附加参数:

int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);

pselect使用sigmask参数来配置哪些信号可以中断它

当前被阻止的信号集合称为 信号掩码。每个进程都有自己的信号掩码。当您创建 新进程(请参阅创建进程),它继承其父进程的掩码。 您可以通过修改 信号掩码。

来源 : https://www.gnu.org/software/libc/manual/html_node/Process-Signal-Mask.html

https://linux.die.net/man/2/pselect

https://www.linuxprogrammingblog.com/code-examples/using-pselect-to-avoid-a-signal-race

由于您的第二个问题,有多种流程同步算法,请参阅 https://www.geeksforgeeks.org/introduction-of-process-synchronization/以及此页面上的链接或 https://en.wikipedia.org/wiki/Sleeping_barber_problem 和相关页面。所以基本上信号只是 Linux 中 IPC 的一条路径,参见 IPC 在 Linux 上使用信号

(忽略问题的所有信号部分,只回答

如果我有线程(生产者和消费者),以及每个(消费者)线程 正在使用pselect,有没有办法只中断一个 来自另一个(生产者)线程的(消费者)线程?

,因为标题并不意味着使用信号)。

我知道的最简单方法是让线程公开一个文件描述符,该文件描述符将始终包含在 p/select 监控描述符中,因此它始终监视至少一个。如果其他线程写入该线程,则 p/select 调用将返回:

struct thread {
pthread_t tid;
int wake;
...
}
void *thread_cb(void *t) {
struct thread *me = t;
t->wake = eventfd(0, 0);
...
fd_set readfds;
// Populate readfds;
FD_SET(t->wake, &readfds);
select(...);
}
void interrupt_thread(struct thread *t) {
eventfd_write(t->wake, 1);
}

如果没有可用的 eventfd,则可以将其替换为经典(更详细)管道或其他类似的通信机制。

最新更新