如何通过基本信号处理在c中同步多个进程

如何通过基本信号处理在c中同步多个进程,c,concurrency,C,Concurrency,人们。对于一个学术练习,我必须在c For nix平台上实现一个程序,该程序通过信号处理来同步多个进程,只使用信号、暂停、终止和fork基本函数。 我搜索了谷歌,但没有找到任何明确的例子:我希望你们其中一位的智慧能照亮我的道路。 谢谢 需要注意的一件重要事情是,Linux(至少,可能还有许多其他Unice)可以将同一类型的多个信号压缩到一个实例中。因此,如果你向一个进程发送一个值为x的信号,那么这个进程一定会收到它;但是,如果您发送2个或多个值为x的信号,则该过程只能保证接收其中至少一个信号 此

人们。对于一个学术练习,我必须在c For nix平台上实现一个程序,该程序通过信号处理来同步多个进程,只使用信号、暂停、终止和fork基本函数。 我搜索了谷歌,但没有找到任何明确的例子:我希望你们其中一位的智慧能照亮我的道路。
谢谢

需要注意的一件重要事情是,Linux(至少,可能还有许多其他Unice)可以将同一类型的多个信号压缩到一个实例中。因此,如果你向一个进程发送一个值为x的信号,那么这个进程一定会收到它;但是,如果您发送2个或多个值为x的信号,则该过程只能保证接收其中至少一个信号

此外,信号不保证按发送顺序接收

(为什么?在幕后,Linux为每个进程维护一个位掩码,记录发送的未完成信号。每当调度程序唤醒进程时,所有未完成信号的信号处理程序都会以任意顺序运行。)

所有这一切意味着信号通常不适合同步过程。它们仅在信号之间的时间间隔相对于接收过程的唤醒时间间隔较大时可靠工作。如果一个进程被阻塞了很多时间,唤醒事件可以任意分开


结论:不要将信号用于IPC。

需要注意的一件重要事情是,Linux(至少,可能还有许多其他Unice)可以将相同类型的多个信号压缩到一个实例中。因此,如果你向一个进程发送一个值为x的信号,那么这个进程一定会收到它;但是,如果您发送2个或多个值为x的信号,则该过程只能保证接收其中至少一个信号

此外,信号不保证按发送顺序接收

(为什么?在幕后,Linux为每个进程维护一个位掩码,记录发送的未完成信号。每当调度程序唤醒进程时,所有未完成信号的信号处理程序都会以任意顺序运行。)

所有这一切意味着信号通常不适合同步过程。它们仅在信号之间的时间间隔相对于接收过程的唤醒时间间隔较大时可靠工作。如果一个进程被阻塞了很多时间,唤醒事件可以任意分开

结论:不要为IPC使用信号。

在收到信号之前不会返回。因此,基本设计是:

  • fork
    来创建必要的工人
  • 在每个工人中捕获
    SIGINT
    。处理程序设置一个标志,表示进程在完成当前作业后应退出
  • 每个进程都能正常工作,然后暂停。除非收到
    SIGINT
    ,否则重复此步骤(在
    pause
    之前和之后进行测试)
  • 当一个进程的功可用于另一个进程时,它用
    SIGCONT
  • 当一个进程没有更多的工作时,用SIGINT发出信号
这还不包括对共享数据的同步访问。为此,您可以添加一条附加规则:

  • 当一个进程向另一个进程发出工作可用的信号时,它应该暂停
当然,这与并发编程的目的背道而驰

由于大多数系统调用都会被信号中断(导致它们返回-1,
errno
设置为
EINTR
),因此您必须处理此意外事件,重复每个受影响的系统调用,直到成功为止。例如:

while ((readCount = read(...)) < 0 && errno == EINTR) {}
while((readCount=read(…)<0&&errno==EINTR){}
在收到信号之前不会返回。因此,基本设计是:

  • fork
    来创建必要的工人
  • 在每个工人中捕获
    SIGINT
    。处理程序设置一个标志,表示进程在完成当前作业后应退出
  • 每个进程都能正常工作,然后暂停。除非收到
    SIGINT
    ,否则重复此步骤(在
    pause
    之前和之后进行测试)
  • 当一个进程的功可用于另一个进程时,它用
    SIGCONT
  • 当一个进程没有更多的工作时,用SIGINT发出信号
这还不包括对共享数据的同步访问。为此,您可以添加一条附加规则:

  • 当一个进程向另一个进程发出工作可用的信号时,它应该暂停
当然,这与并发编程的目的背道而驰

由于大多数系统调用都会被信号中断(导致它们返回-1,
errno
设置为
EINTR
),因此您必须处理此意外事件,重复每个受影响的系统调用,直到成功为止。例如:

while ((readCount = read(...)) < 0 && errno == EINTR) {}
while((readCount=read(…)<0&&errno==EINTR){}

Geez,虐待狂教授警报。他听说过锁和信号灯吗?@atreyu:flock()怎么样?谢谢你的反馈:@Keith semaphores在下一个练习中,这只是为了教育虐待目的@outis good point,但恐怕我只能使用信号处理的基本功能Geez,虐待狂教授alert。他听说过锁和信号灯吗?@atreyu:flock()怎么样?谢谢你的反馈:@Keith semaphores在下一个练习中,这只是为了教育性的施虐目的@outis good point,但恐怕我只能使用信号处理的基本功能虽然这似乎是个好主意,如果两个进程都在短时间内向另一个进程发送SIGCONT,则该进程可能会失败,因为该进程可能只接收SIGCONT