gpt4 book ai didi

c - 简单的信号同步

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:35:34 25 4
gpt4 key购买 nike

该程序旨在永久发出交易信号。 SIGUSR1 被父级捕获,SIGUSR2 被子级捕获。当他们捕捉到自己的信号时,他们只玩旗帜。我先让parent跑,就是先parent发信号。 child 等待 pause() 它的进程,直到它运行它的捕手。我以为我应用了一个简单的同步,但似乎不是。但是,如果我在 usleep(1000) 中发表评论,代码就可以运行。喜欢

initial value, flag = -99
child process, flag = 0
parent process, flag = 1
child process, flag = 0
parent process, flag = 1
child process, flag = 0
.
.
.
child process, flag = 0
parent process, flag = 1
child process, flag = 0
parent process, flag = 1
child process, flag = 0
.
.
.

但是没有 sleep ,我得不到我想要的。我想在不 sleep 的情况下实现我的意图。错误的输出是,

initial value, flag = -99
parent process, flag = -99
waits forever..................

如何按预期运行?但是,这种行为的原因是什么?顺便说一句,我必须只对没有信号量、互斥量等的信号应用同步。所有 posix 信号功能,除了 sleep 、纳米 sleep 或暂停和忙等待,都可以像 sigaction、sigsuspend 等一样使用。

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

volatile sig_atomic_t flag = -99; // child = 0, parent = 1;



void catcher(int sig) {
switch (sig) {
case SIGUSR1 : flag = 1; break;
case SIGUSR2 : flag = 0; break;
}
}

int safeBlockParent(int signum) {

sigset_t maskall, maskmost, maskold;



sigfillset(&maskall);
sigfillset(&maskmost);
sigdelset(&maskmost, signum);
sigprocmask(SIG_SETMASK, &maskall, &maskold);
if (flag == 0)
sigsuspend(&maskmost);
sigprocmask(SIG_SETMASK, &maskold, NULL);
}

int safeBlockChild(int signum) {
sigset_t maskall, maskmost, maskold;

sigfillset(&maskall);
sigfillset(&maskmost);
sigdelset(&maskmost, signum);
sigprocmask(SIG_SETMASK, &maskall, &maskold);
if (flag == 1)
sigsuspend(&maskmost);
sigprocmask(SIG_SETMASK, &maskold, NULL);
}

void ChildProcess() {


while(1) {
safeBlockChild(SIGUSR2);
fprintf(stderr, "child process, flag = %d\n", flag);
kill( getppid(), SIGUSR1 );
}
}

void ParentProcess(pid_t childPid) {

flag = 1;

while(1) {
//usleep(1000);
fprintf(stderr, "parent process, flag = %d\n", flag);
kill( childPid, SIGUSR2 );
safeBlockParent(SIGUSR1);

}
}

int main() {

pid_t pid;
struct sigaction sact = { 0 };

fprintf(stderr, "initial value, flag = %d\n", flag);

sigemptyset( &sact.sa_mask );
sact.sa_flags = 0;
sact.sa_handler = catcher;

if (sigaction (SIGUSR1, &sact, NULL) < 0) {
perror("sigaction sigusr1 error");
exit(1);
}

if (sigaction (SIGUSR2, &sact, NULL) < 0) {
perror("sigaction sigusr2 error");
exit(2);
}


pid = fork();
if (pid < 0) { perror("fork problem"); exit(3); }

if (pid == 0) {

//kill(getppid(), SIGUSR1);
ChildProcess();
}

else {
ParentProcess(pid);
//wait(NULL);
}

return 0;
}

代码有时卡住,有时运行。

最佳答案

你有两个竞争条件:

  1. 父进程可以在子进程有机会为 SIGUSR2 注册信号处理程序之前发送信号。
  2. 一个进程可以在另一个进程处于 pause 之外时发送信号。

后者可能在第一轮发生,此时子进程尚未到达pause,但父进程已发送SIGUSR2。这会导致您看到的效果。

关于c - 简单的信号同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49619309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com