天天看點

Linux中信号(帶參信号)

加粗樣式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;
}
           

繼續閱讀