gpt4 book ai didi

multithreading - 多进程系统中与sigwait相关的混淆

转载 作者:行者123 更新时间:2023-12-01 05:28:56 25 4
gpt4 key购买 nike

我很难理解多进程系统中的 IPC。我有这个系统,其中有三个子进程向它们的进程组发送两种类型的信号。有四种类型的信号处理过程负责特定类型的信号。

有一个监视过程,它等待两个信号,然后进行相应的处理。当我运行这个程序一段时间时,监控过程似乎并没有像信号处理过程一样拾取信号。我可以在日志中看到信号只是生成但根本没有处理。

我的代码如下

#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <cstdio>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

using namespace std;

double timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return (double)tp.tv_sec + tp.tv_usec / 1000000.;
}

double getinterval() {
srand(time(NULL));
int r = rand()%10 + 1;
double s = (double)r/100;
}

int count;
int count_1;
int count_2;
double time_1[10];
double time_2[10];


pid_t senders[1];
pid_t handlers[4];
pid_t reporter;

void catcher(int sig) {
printf("Signal catcher called for %d",sig);
}

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

void signal_catcher_int(int);

pid_t pid,w;
int status;

if(signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
perror("1");
return 1;
}

if(signal(SIGUSR2 ,SIG_IGN) == SIG_ERR) {
perror("2");
return 2;
}

if(signal(SIGINT,signal_catcher_int) == SIG_ERR) {
perror("3");
return 2;
}

//Registering the signal handler
for(int i=0; i<4; i++) {
if((pid = fork()) == 0) {
cout << i << endl;
//struct sigaction sigact;
sigset_t sigset;
int sig;
int result = 0;

sigemptyset(&sigset);

if(i%2 == 0) {

if(signal(SIGUSR2, SIG_IGN) == SIG_ERR) {
perror("2");
return 2;
}

sigaddset(&sigset, SIGUSR1);
sigprocmask(SIG_BLOCK, &sigset, NULL);
} else {
if(signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
perror("2");
return 2;
}

sigaddset(&sigset, SIGUSR2);
sigprocmask(SIG_BLOCK, &sigset, NULL);
}

while(true) {
int result = sigwait(&sigset, &sig);
if(result == 0) {
cout << "The caught signal is " << sig << endl;
}
}
exit(0);

} else {
cout << "Registerd the handler " << pid << endl;
handlers[i] = pid;
}
}

//Registering the monitoring process
if((pid = fork()) == 0) {
sigset_t sigset;
int sig;
int result = 0;

sigemptyset(&sigset);
sigaddset(&sigset, SIGUSR1);
sigaddset(&sigset, SIGUSR2);

sigprocmask(SIG_BLOCK, &sigset, NULL);

while(true) {
int result = sigwait(&sigset, &sig);
if(result == 0) {
cout << "The monitored signal is " << sig << endl;
} else {
cout << "error" << endl;
}
}

} else {
reporter = pid;
}


sleep(3);
//Registering the signal generator
for(int i=0; i<1; i++) {
if((pid = fork()) == 0) {

if(signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
perror("1");
return 1;
}

if(signal(SIGUSR2, SIG_IGN) == SIG_ERR) {
perror("2");
return 2;
}
srand(time(0));
while(true) {
volatile int signal_id = rand()%2 + 1;
cout << "Generating the signal " << signal_id << endl;
if(signal_id == 1) {
killpg(getpgid(getpid()), SIGUSR1);
} else {
killpg(getpgid(getpid()), SIGUSR2);
}
int r = rand()%10 + 1;
double s = (double)r/100;
sleep(s);
}

exit(0);
} else {
cout << "Registered the sender " << pid << endl;
senders[i] = pid;

}

}


while(w = wait(&status)) {
cout << "Wait on PID " << w << endl;
}

}



void signal_catcher_int(int the_sig) {
//cout << "Handling the Ctrl C signal " << endl;
for(int i=0; i<1; i++) {
kill(senders[i],SIGKILL);
}

for(int i=0; i<4; i++) {
kill(handlers[i],SIGKILL);
}

kill(reporter,SIGKILL);

exit(3);
}

有什么建议?

这里也是一个输出示例

在一开始的时候
Registerd the handler 9544
Registerd the handler 9545
1
Registerd the handler 9546
Registerd the handler 9547
2
3
0
Registered the sender 9550
Generating the signal 1
The caught signal is 10
The monitored signal is 10
The caught signal is 10
Generating the signal 1
The caught signal is 10
The monitored signal is 10
The caught signal is 10
Generating the signal 1
The caught signal is 10
The monitored signal is 10
The caught signal is 10
Generating the signal 1
The caught signal is 10
The monitored signal is 10
The caught signal is 10
Generating the signal 2
The caught signal is 12
The caught signal is 12
The monitored signal is 12
Generating the signal 2
Generating the signal 2
The caught signal is 12
The caught signal is 12
Generating the signal 1
The caught signal is 12
The monitored signal is 10
The monitored signal is 12
Generating the signal 1
Generating the signal 2
The caught signal is 12
Generating the signal 1
Generating the signal 2
10
The monitored signal is 10
The caught signal is 12
Generating the signal 1
The caught signal is 12
The monitored signal is GenThe caught signal is TheThe caught signal is 10
Generating the signal 2

稍后的
The monitored signal is GenThe monitored signal is 10
Generating the signal 1
Generating the signal 2
The caught signal is 10
The caught signal is 10
The caught signal is 10
The caught signal is 12
Generating the signal 1
Generating the signal 2
Generating the signal 1
Generating the signal 1
Generating the signal 2
Generating the signal 2
Generating the signal 2
Generating the signal 2
Generating the signal 2
Generating the signal 1
The caught signal is 12
The caught signal is 10
The caught signal is 10
Generating the signal 2
Generating the signal 1
Generating the signal 1
Generating the signal 2
Generating the signal 1
Generating the signal 2
Generating the signal 2
Generating the signal 2
Generating the signal 1
Generating the signal 2
Generating the signal 1
Generating the signal 2
Generating the signal 2
The caught signal is 10
Generating the signal 2
Generating the signal 1
Generating the signal 1

正如您最初看到的,信号是由我的信号处理程序和监控进程生成和处理的。但后来信号产生了很多,但它的过程并不像以前那样大。此外,我可以看到监控过程中的信号处理非常少

任何人都可以提供一些见解。这是怎么回事?

最佳答案

如果多个相同类型的信号处于待处理状态,Linux 默认只发送一个这样的信号。这与 sigwait documentation 一致:

If prior to the call to sigwait() there are multiple pending instances of a single signal number, it is implementation-dependent whether upon successful return there are any remaining pending signals for that signal number.



所以你的程序的输出取决于调度程序,如果多次调用 kill 并且调度程序没有同时唤醒监控进程,则相同类型的信号会合并为一个。

Linux 允许 change默认行为。

关于multithreading - 多进程系统中与sigwait相关的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12452191/

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