解决linux多个进程互斥问题

  • 需求

1-父进程fork出子进程C1,C2,C3,和D1,需要子进程C1,C2,C3同时运行或者子进程D1单独运行。
2-子进程C1,C2,C3调用相同的函数,只是传入的参数不同。子进程D1调用与之不同的函数。
3-使用信号量(PV操作)来解决此问题。

  • 解决方法

初始化信号量的值为3,在执行子进程D1时,进行PV操作,将信号量的值先-3,子进程D1执行完成后将信号量的值+3,而在执行子进程C1,C2,C3时,由于调用相同的函数,可以在进行PV操作时,将信号量的值先-1,执行完成后将信号量的值+1,就可以解决。测试用例和测试结果如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>

int sem_id;
key_t sem_key;

/* 建立信号量 */
int initsem(int *semid, key_t semkey)
{
	int    res = 0;

	if ((*semid = semget(semkey, 3, IPC_CREAT | 0666)) == -1)  
	{
		return -1;
	}
	else
		res = semctl(*semid, 0, SETVAL, 3);

	if (*semid == -1 || res == -1)
	{
		return  -1;
	}
	else
		return   0;
}

/*  V 操作 */
int V(int Semid, int flag,short value)
{
	struct sembuf sops[1];
	int rtn;
	sops[0].sem_num = flag;
	sops[0].sem_op = value;
	sops[0].sem_flg = SEM_UNDO;
	rtn = semop(Semid, sops, 1);
	if(rtn == -1)
	{
		return -1;
	}
	return 0;
}
/*  P 操作  */
int P(int Semid, int flag, short value)
{

	struct sembuf sops[1];
	int rtn;
	sops[0].sem_num = flag;
	sops[0].sem_op = value;
	sops[0].sem_flg = SEM_UNDO;
	rtn=semop(Semid,sops,1);
	if(rtn==-1)
	{
		return -1;
	}
	return 0;
}
void same_handle(int value)
{
	P(sem_id, 0 ,-1);
	printf("same handle begin\n");
	value++;
	sleep(15);
	V(sem_id, 0 ,+1);
}
void oneself_handle(int value)
{
	P(sem_id, 0 ,-3);
	printf("oneself handle begin\n");
	value+=2;
	sleep(20);
	V(sem_id, 0,+3);
}
int main(void)
{
	pid_t pid[5] = {0};
	
	/* 初始化信号量 */
	initsem(&sem_id, sem_key);
		
	pid[0] = fork();
	if(pid[0] == 0)
	{
		int l = 0;
		oneself_handle(l);
		printf("process one exit,l:%d\n",l);
		exit(0);
	}
	pid[1] = fork();
	if(pid[1] == 0)
	{
		int i = 0;
		same_handle(i);
		printf("process two exit,i:%d\n",i);
		exit(0);
	}
	pid[2] = fork();
	if(pid[2] == 0)
	{
		int j = 0;
		same_handle(j);
		printf("process three exit,j:%d\n",j);
		exit(0);
	}
	pid[3] = fork();
	if(pid[3] == 0)
	{
		int k = 0;
		same_handle(k);
		printf("process forth exit,k:%d\n",k);
		exit(0);
	}
	while(1);
	while(1);
}

测试结果:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
首先,子进程D1运行,获得信号量,当前信号量值为0,子进程C1,C2,C3阻塞,当D1执行完事后,变成僵尸进程,子进程C1,C2,C3同时获得信号量开始运行,最后同时退出变成僵尸进程。

由此可见,信号量在进程之间起着互斥、同步的作用,可以达到很好的效果。


版权声明:本文为Qinxiangling原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。