gpt4 book ai didi

c - sigwait() 反复被 SIGUSR1 解锁

转载 作者:太空狗 更新时间:2023-10-29 15:08:06 29 4
gpt4 key购买 nike

我正在编写一个程序,它从一个文件中获取一系列 UNIX 命令并按顺序执行它们。为了保持一切有序,我必须初始化每个命令并通过 sigwait() 等待 SIGUSR1。当每个命令都初始化后,每个命令都可以执行。

用法:> program.c input.txt

然而,似乎SIGUSR1被重复调用,完全超越了sigwait()。这里发生了什么?我尝试了很多不同的东西,但它最近模仿了 this answer .换句话说,我希望在初始化后立即为命令发出信号。我希望信号在所有命令完全初始化后畅通

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


void on_sigusr1(int sig)
{
// Note: Normally, it's not safe to call almost all library functions in a
// signal handler, since the signal may have been received in a middle of a
// call to that function.
printf("SIGUSR1 received!\n");
}

int main(int arc, char* argv[])
{


FILE *file;
file = fopen(argv[1] ,"r");

int BUF_SIZE = 100;

char *token;
char buffer[BUF_SIZE];
char programs[BUF_SIZE];
char *commands[BUF_SIZE];

int i = 0;
int counter = 1;

while (fgets(buffer, sizeof buffer, file ) != NULL)
{
strcpy(programs, buffer);

int length = strlen(buffer)-1;
if (buffer[length] == '\n')
{
buffer[length] = '\0';
}

i = 0;
token = strtok(buffer," ");
while(token != NULL)
{
commands[i++] = token;
token = strtok(NULL, " ");
}
commands[i] = 0;

pid_t pids[counter];


// Set a signal handler for SIGUSR1
signal(SIGUSR1, &on_sigusr1);

// At program startup, SIGUSR1 is neither blocked nor pending, so raising it
// will call the signal handler
raise(SIGUSR1);

// Now let's block SIGUSR1
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGUSR1);
sigprocmask(SIG_BLOCK, &sigset, NULL);

// SIGUSR1 is now blocked, raising it will not call the signal handler
printf("About to raise SIGUSR1\n");
raise(SIGUSR1);
printf("After raising SIGUSR1\n");


for(i = 0; i < counter; ++i)
{
pids[i] = fork();

if(pids[i] > 0)
{
printf("Child process %d ready to execute command %s", getpid(), programs);
// SIGUSR1 is now blocked and pending -- this call to sigwait will return
// immediately
int sig;
int result = sigwait(&sigset, &sig);
if(result == 0) {
printf("Child process %d executing command %s", getpid(), programs);
execvp(commands[0], commands);
}
}
}

// All programs have been launched
for(i = 0; i < counter; ++i)
{
wait(&pids[i]);
}

// All programs are waiting to execute
for (i = 0; i < counter; ++i)
{
// SIGUSR1 is now no longer pending (but still blocked). Raise it again and
// unblock it
raise(SIGUSR1);
printf("About to unblock SIGUSR1\n");
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
printf("Unblocked SIGUSR1\n");
}
}

exit(0);
fclose(file);
return 0;
}

更新:尝试将 signal() 更改为 sigaction()。没有变化。

最佳答案

您应该考虑调用 sigwait after 检查该 pid 是否是一个子进程。

所以也许放

信号;

int 结果 = sigwait(&sigset, &sig);

在 if 语句中检查 pid 是否为 == 0,这表明它是一个 child 。否则,您将等待父进程。

如果 pid 大于 0,则为父进程 ID,如果小于零,则为错误。

然后对于 pid 数组中的每个进程,您将调用 kill(pid_array[i], SIGUSR1) 来解除阻塞。

关于c - sigwait() 反复被 SIGUSR1 解锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26585228/

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