加粗樣式Linux中信号(帶參信号)## 标題
要求建立四個程序A->B->C->D
A—>發送SIGUSR1信号并攜帶一個整型資料2001,B程序收到資料後對2001加1,在通過SIGUSR2信号發送給程序C,同樣程序C收到SIGUSR2信号後,在把資料2002再累加1,通過發送SIGRTMIN發送給程序DD收到信号後,在發送SIGUSR2信号給程序A.最後程序A在信号處理函數中列印初最後的整型數組。(要求A程序在執行SIGUSR1信号處理函數的時候屏蔽SIGUSR2信号)
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
pid_t pidA,father, son; //判斷屬于哪個程序
void sigaction_fun(int num, siginfo_t* info, void* vo)
{
if (father == 0 && son != 0) //D發送給A
{
cout << "A程序value:" << info->si_int << endl;
}
else if (father !=0 && son != 0)
{
if (num == 10) //A發送給B
{
cout << "B程序value:" << info->si_int << endl;
union sigval value;
value.sival_int = ++(info->si_int);
sleep(1);
sigqueue(son, SIGUSR2, value); //發送給C程序
}
else if (num == 12) //B發送給C
{
cout << "C程序value:" << info->si_int << endl;
union sigval value;
value.sival_int = ++(info->si_int);
sleep(1);
sigqueue(son, SIGRTMIN, value); //發送給C程序
}
}
else if (father != 0 && son == 0)
{
cout << "D程序value:" << info->si_int << endl;
union sigval value;
value.sival_int = info->si_int;
sleep(1);
sigqueue(pidA, SIGUSR2, value); //發送給D程序
}
}
int main()
{
pidA = fork();
if (pidA < 0)
{
perror("fork1 error");
}
else if (pidA > 0)
{
std::cout << "A:" << getpid() << endl;
//準備一個信号容器(需要屏蔽的信号放在裡面)
sigset_t array;
//容器初始化
sigemptyset(&array);
//向容器添加需要屏蔽的信号
sigaddset(&array, SIGUSR2);
//sigaddset屏蔽信号處理函數在運作時的信号,使它排隊
//如果用的是sigprocmask的話就是真的屏蔽阻塞掉完全收不到
/*if (sigprocmask(SIG_BLOCK, &array, NULL) < 0)
{
perror("sigprocmask error");
return 0;
}*/
struct sigaction act1;
act1.sa_sigaction = sigaction_fun; // 綁定函數
act1.sa_flags = SA_SIGINFO; // 聲明是帶資料的信号
sigaction(SIGUSR2, &act1, NULL); // A 綁定 SIGUSR2
father = 0;
son = pidA;
union sigval value;
value.sival_int = 2001;
sleep(1); //睡眠1秒
sigqueue(son, SIGUSR1, value); //發送給B程序
while (1) {};
}
else if (pidA == 0)
{
pidA = getppid();
pid_t pidB = fork();
if (pidB < 0)
{
perror("fork1 error");
}
else if (pidB > 0)
{
std::cout << "B:" << getpid() << endl;
//标記位
father = getppid(); //擷取程序A的PID
son = pidB;
struct sigaction act2;
act2.sa_sigaction = sigaction_fun; // 綁定函數
act2.sa_flags = SA_SIGINFO; // 聲明是帶資料的信号
sigaction(SIGUSR1, &act2, NULL); // B 綁定 SIGUSR1
while (1) {};
}
else if (pidB == 0)
{
pid_t pidC = fork();
if (pidC < 0)
{
perror("fork3 error");
}
else if (pidC > 0)
{
std::cout << "C:" << getpid() << endl;
//标記位
father = getppid();
son = pidC;
struct sigaction act3;
act3.sa_sigaction = sigaction_fun; // 綁定函數
act3.sa_flags = SA_SIGINFO; // 聲明是帶資料的信号
sigaction(SIGUSR2, &act3, NULL); // C 綁定 SIGUSR2
while (1) {};
}
else if (pidC == 0)
{
pid_t pidD = fork();
if (pidD < 0)
{
perror("fork4 error");
}
else if (pidD > 0)
{
std::cout << "D:" << getpid() << endl;
//标記位
father = getppid();
son = 0;
struct sigaction act4;
act4.sa_sigaction = sigaction_fun; // 綁定函數
act4.sa_flags = SA_SIGINFO; // 聲明是帶資料的信号
sigaction(SIGRTMIN, &act4, NULL); // D 綁定 SIGRTMIN
while (1) {};
}
else if (pidD == 0)
{
while (1) {};
}
}
}
}
return 0;
}