gpt4 book ai didi

c - Ping-pong 在 POSIX 中使用 kill 和 flags

转载 作者:行者123 更新时间:2023-12-04 10:26:59 24 4
gpt4 key购买 nike

我正在尝试通过在 C 中使用 POSIX 信号来实现进程间通信,尤其是我正在编写 Ping-Pong 问题。所以这是我的源代码:

#define CHILD 0
#define PARENT 1

int flag[2];

void handler(int sig) {
if (sig == SIGUSR1) {
flag[PARENT] = 1;
} else {
flag[CHILD] = 1;
}
return;
}

void child_process() {
while (1) {
printf("Ping!\n");
kill(getppid(), SIGUSR2);
while (flag[PARENT] == 0) { }
}
return;
}

void parent_process(pid_t t) {
while (1) {
//kill(t, SIGUSR1);
while (flag[CHILD] == 0) { }
printf("Pong!\n");

kill(t, SIGUSR1);
}
return;
}

void setup() {
flag[CHILD] = 0;
flag[PARENT] = 0;
signal(SIGUSR1, handler);
signal(SIGUSR2, handler);
}

int main(int argc, char* argv[]) {
setup();
pid_t t = fork();
if (t == 0) {
child_process();
} else {
parent_process(t);
}
return 0;
}

我的程序运行不正常,因为有时我会收到“Pong!” “乒!” “乒!”或“砰!” “砰!”输出。有什么问题?

还有一个问题,我处理信号的方式是否正确?或者有更高级的方法来做到这一点?

最佳答案

(1) parent 和 child 不共享相同的内存。 flag[CHILD] 和 flag[PARENT] 永远不会知道对方,因为它们是不同进程中的不同副本。

(2) 是的,关于信号处理的几乎所有内容对于您尝试执行的操作都是错误的。您正在尝试同步信号,因此您需要使用一种实际同步它们的机制,例如signsuspend.

#define _POSIX_C_SOURCE 1
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <errno.h>

#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)

void sig_hand(int sig) {}

sigset_t saveMask, blockMask;

void child_process()
{
int x = 0;

while(x < 10)
{
if (sigsuspend(&saveMask) == -1 && errno != EINTR)
errExit("sigsuspend");

printf("Pong %d!\n", ++x);

kill(getppid(), SIGUSR1);
}

return ;
}

void parent_process(pid_t pid)
{
int y = 0;

while (y < 10)
{
printf("Ping %d!\n", ++y);

kill(pid, SIGUSR1);

if (sigsuspend(&saveMask) == -1 && errno != EINTR)
errExit("sigsuspend");
}

return ;
}


int main(int argc, char* argv[])
{
//block SIGUSR1 in parent & child until ready to process it
sigemptyset(&blockMask);
sigaddset(&blockMask, SIGUSR1);

if (sigprocmask(SIG_BLOCK, &blockMask, &saveMask) == -1)
errExit("sigprocmask");

//set up signal handler for parent & child
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = sig_hand;

if (sigaction(SIGUSR1, &sa, NULL) == -1)
errExit("sigaction");

pid_t pid = fork();

if (pid == 0)
child_process();
else
parent_process(pid);

return 0;
}

关于c - Ping-pong 在 POSIX 中使用 kill 和 flags,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23047068/

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