gpt4 book ai didi

c - 使用 SIGUSR1 的两个进程之间的 Posix 可靠信号

转载 作者:太空宇宙 更新时间:2023-11-04 07:29:42 24 4
gpt4 key购买 nike

我必须在两个不同的终端上运行进程(服务器和客户端)。客户端读取用户输入,将其保存到文件 (hello.txt),发出 SIGUSR1 信号,然后休眠。然后服务器醒来,读取文件 (hello.txt),打印它,向客户端发出它工作的信号,然后休眠。然后客户端醒来,打印它成功,然后等待另一个用户输入。

稍后还有更多内容,但这就是我目前想要完成的全部工作。我很难找到在两个独立的、不相关的进程之间使用 sigaction 和 SIGUSR1 的示例。这是我到目前为止的代码:

服务器.c

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

volatile sig_atomic_t myFlag = 0;
static void myHandler(int);
struct sigaction newAction, oldAction;


int main(int argc, char* argv[])
{
//setup signal stuff
sigset_t zeromask;
sigemptyset(&newAction.sa_mask);
sigemptyset (&oldAction.sa_mask);
sigemptyset(&zeromask);
newAction.sa_flags = 0;
newAction.sa_handler = myHandler;
sigaddset (&newAction.sa_mask, SIGUSR1);
if ( sigaction(SIGUSR1, &newAction, &oldAction))
return;

for ( ; ; ) {
//Loop
//This is so I can manually enter the pid into the client
printf("%d\n",getpid());
while(myFlag == 0)
sigsuspend (&zeromask);
myFlag = 0;
printf("Got signal, process it\n");

//signal occured process it
}

sigprocmask (SIG_SETMASK, &oldAction.sa_mask, NULL);
exit(0);
}

static void myHandler(int sigNo) {
myFlag = 1;

printf("finally made it");
sigprocmask (SIG_BLOCK, &newAction.sa_mask, &oldAction.sa_mask);
return;
}

客户端.c

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

volatile sig_atomic_t myFlag = 0;
static void myHandler(int);
struct sigaction newAction, oldAction;


int main(int argc, char* argv[])
{
printf("begin\n");
//Signal stuff
sigset_t zeromask;
sigemptyset(&newAction.sa_mask);
newAction.sa_flags = 0;
newAction.sa_handler = myHandler;
sigemptyset (&oldAction.sa_mask);
sigemptyset(&zeromask);
sigaddset (&newAction.sa_mask, SIGUSR1);
if ( sigaction(SIGUSR1, &newAction, &oldAction))
return;
sigprocmask (SIG_BLOCK, &newAction.sa_mask, &oldAction.sa_mask);

//loop
for ( ; ; ) {
printf("This is where you would get user input\n");
//Signal Server
//For now I just manually enter the pid that was printed out when I ran server.c. This does not work and I do not think it is the right thing to do
kill(27514,SIGUSR1);
//loop while waiting for server to respond
while(myFlag == 0)
sigsuspend (&zeromask);

myFlag = 0;
printf("this is where you would process return signal\n");
//signal occured process it
}

sigprocmask (SIG_SETMASK, &oldAction.sa_mask, NULL);
exit(0);
}

static void myHandler(int sigNo) {
myFlag = 1;
sigprocmask (SIG_BLOCK, &newAction.sa_mask, &oldAction.sa_mask);
return;
}

现在所有这些代码应该做的是从客户端向服务器发送信号。从那里我将实现其余部分。但是,这不起作用,我似乎无法弄清楚。

kill 是用于实现 SIGUSR1 的正确命令吗?我需要知道每个客户端和服务器的 PID 以便它们进行通信吗?我是不是完全做错了事?

最佳答案

你没有说明实际发生了什么,但要回答你的问题:

“kill 是用于实现 SIGUSR1 的正确命令吗?”是的。

“我需要知道每个客户端和服务器的 PID 以便它们进行通信吗?”是的。

“我是不是完全做错了事?”是的。

使用信号的主要问题是 1) 它会在您的程序执行过程中随时到达,并且 2) 您只能在特定时间准备好处理它。

您上面的代码只会正确处理信号,如果它恰好在 sigsuspend() 中,等待。并非每时每刻都是如此!当您处于循环的其他部分时,即当您将 kill() 发送到另一个进程时,请考虑如果另一个进程 kill() 在您再次到达 sigsuspend 之前返回会发生什么......您赢了等待信号,它会来来去去。您的实现不可靠。

更可靠的实现是在进程之间使用套接字连接;你可以通过这样的连接来传递信号甚至数据本身。事实上有很多方法可以做到这一点,参见http://en.wikipedia.org/wiki/Inter-process_communication (而且您似乎在使用上面的 POSIX 接口(interface))。

结果是信号是异步的,会中断任何程序的流程,并且特定于您的程序,您并不总是为它做好准备,如果您错过了它,它就消失了。使用套接字(或管道或其他具有实际文件描述符的东西),数据(您的信号)将导致 select() 或 poll() 返回,而不是仅仅飞过。

关于c - 使用 SIGUSR1 的两个进程之间的 Posix 可靠信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14965975/

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