使用信号实现进程同步(踢皮球游戏)

学习了信号机制,我们就可以利用信号机制实现进程间同步了,比如我们希望一个进程处理完某件事情后再通知另外一个进程继续处理某件事情,这种需求实现的方法有很多,但是用信号实现是最方便的,这里我们举例用了一个踢皮球的小游戏充分展示了利用信号实现进程间同步的功能。程序执行后效果如下:


2015-07-01_212759

A 进程打印数字 1 后发送信号给 B 进程,B 进程收到信号将打印的值 +1 再输出到屏幕上,再发送信号给 A 进程,依次循环。

【实现代码】

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

void sigdoAction(int num, siginfo_t* siginfo, void* p)
{
	int tmp = siginfo->si_int;			// 得到结构体中存放的变量值,这里可以判断是否到了100
	int nProcessID = siginfo->si_pid;	// 得到发送信号进程的进程PID
	printf("sigdoAction: tmp = %d, ProcessID = %d, Send Signal ProcessID = %d\n", tmp, getpid(), nProcessID);

	// 将皮球踢回去
	sleep(1);								// 等待一秒,不然太快
	tmp++;									// 皮球值+1
	union sigval unsig;						// 定义 sigqueue 所需结构体
	unsig.sival_int = tmp;					// 初始化结构体成员(皮球)
	sigqueue(nProcessID, SIGINT, unsig);	// 给参数传递进来的进程发送SIGINT信号
}

int main(int argc, char* argv[])
{
	// 捕获SIGINT信号
	struct sigaction act;
	act.sa_sigaction = sigdoAction;	// 指定信号处理函数
	act.sa_flags = SA_SIGINFO;		// 指定使用那种处理方式
	sigemptyset(&act.sa_mask);		// 清空掩码防止垃圾值
	sigaction(SIGINT, &act, NULL);	// 捕获信号

	// 只有在调用程序时加了进程PID参数才会执行这个操作,主要为了发起互相踢球的第一个信号
	if (argc >= 2)
	{
		int nSendPid = atoi(argv[1]);		// 将传递进来的参数转为int提供给信号发送函数的第一个参数使用

		union sigval unsig;					// 定义 sigqueue 所需结构体
		unsig.sival_int = 1;				// 初始化结构体成员(皮球的初值)
		sigqueue(nSendPid, SIGINT, unsig);	// 给参数传递进来的进程发送SIGINT信号
	}

	while (1)
	{
		sleep(1);
	}

	return 0;
}

 

1 评论

说说你的想法