进程间通信

本文深入探讨了进程间通讯的主要方式,包括管道、信号、消息队列、共享内存和信号量。通过具体代码示例,详细解析了如何使用二值信号与共享内存进行进程间通讯,为读者提供了实践指导。

  今天我们学习了进程间痛讯的几种主要方式:

##管道(pipe)和有名管道(FIFO)

##信号(signal)

##消息队列

##共享内存(semaphore)

##信号量(spcket)

运用二值信号与共享内存的进程间通讯代码如下

shm1.c:
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/sem.h>

#define SHMKEY 1234
#define SHMSIZE 4096
#define SEMKEY 1234

union semun 
{
	int 			 val;	 /* Value for SETVAL */
	struct semid_ds *buf;	 /* Buffer for IPC_STAT, IPC_SET */
	unsigned short	*array;  /* Array for GETALL, SETALL */
	struct seminfo	*__buf;  /* Buffer for IPC_INFO
								(Linux specific) */
};

void sem_p(int id)
{
	struct sembuf s;
	s.sem_num = 0;     //第0个信号量
	s.sem_op = -1;     //减一操作
	s.sem_flg = SEM_UNDO;   //如果进程出现异常退出,信号量恢复初始值
	int ret = semop(id, &s, 1);   //p操作
	if (-1 == ret)
	{
		perror("semop");
	}
}

void sem_v(int id)
{
	struct sembuf s;
	s.sem_num = 0;     //第0个信号量
	s.sem_op = 1;     //减一操作
	s.sem_flg = SEM_UNDO;   //如果进程出现异常退出,信号量恢复初始值
	int ret = semop(id, &s, 1);   //p操作
	if (-1 == ret)
	{
		perror("semop");
	}
}

int main()
{
	int shmid;
	int ret;
	void *shmadder;
	int count = 100;

	shmid = shmget(SHMKEY,SHMSIZE,IPC_CREAT | IPC_EXCL);
	if(-1 == shmid)
	{
		perror("shmget");
		exit(1);
	}

	int semid = semget(SEMKEY, 1, IPC_CREAT | IPC_EXCL);  //创建信号量(1个)
	if (-1 == semid)
	{
		perror("semget");
		exit(1);
	}

	union semun s;
	s.val = 1;   //二值信号量
	ret = semctl(semid, 0, SETVAL, s);  //初始化信号量
	if (-1 == ret)
	{
		perror("semctl");
		exit(1);
	}
	
	shmadder = shmat(shmid,NULL,0);
	if(NULL == shmadder)
	{
		perror("shmat");
		exit(1);
	}

	*(int *)shmadder = count;

	while(1)
	{
		sem_p(semid);     //减一操作
		count = *(int *)shmadder;
		if(count < 0)
		{
			break;
		}
		printf("%d count = %d\n",getpid(),count);
		count--;
		usleep(10000);
		*(int *)shmadder = count;
		sem_v(semid);     //加一操作
	}

	shmdt(shmadder);
	sleep(1);
	shmctl(shmid, IPC_RMID, NULL);   //删除共享内存
	semctl(semid, 0, IPC_RMID);      //删除信号量

	
	return 0;
}

shm2.c:
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/sem.h>


#define SHMKEY 1234
#define SHMSIZE 4096
#define SEMKEY    1234

union semun 
{
	int 			 val;	 /* Value for SETVAL */
	struct semid_ds *buf;	 /* Buffer for IPC_STAT, IPC_SET */
	unsigned short	*array;  /* Array for GETALL, SETALL */
	struct seminfo	*__buf;  /* Buffer for IPC_INFO
								(Linux specific) */
};

void sem_p(int id)
{
	struct sembuf s;
	s.sem_num = 0;     //第0个信号量
	s.sem_op = -1;     //减一操作
	s.sem_flg = SEM_UNDO;   //如果进程出现异常退出,信号量恢复初始值
	int ret = semop(id, &s, 1);   //p操作
	if (-1 == ret)
	{
		perror("semop");
	}
}

void sem_v(int id)
{
	struct sembuf s;
	s.sem_num = 0;     //第0个信号量
	s.sem_op = 1;     //减一操作
	s.sem_flg = SEM_UNDO;   //如果进程出现异常退出,信号量恢复初始值
	int ret = semop(id, &s, 1);   //p操作
	if (-1 == ret)
	{
		perror("semop");
	}
}


int main()
{
	int shmid;
	int ret;
	void *shmadder;
	int count = 100;

	shmid = shmget(SHMKEY,SHMSIZE,0);
	if(-1 == shmid)
	{
		perror("shmget");
		exit(1);
	}

	int semid = semget(SEMKEY, 1, 0);  //获取信号量(1个)
	if (-1 == semid)
	{
		perror("semget");
		exit(1);
	}	
	shmadder = shmat(shmid,NULL,0);
	if(NULL == shmadder)
	{
		perror("shmat");
		exit(1);
	}

	while(1)
	{
		sem_p(semid);     //减一操作
		count = *(int *)shmadder;
		if(count < 0)
		{
			break;
		}
		printf("%d count = %d\n",getpid(),count);
		count--;
		usleep(10000);
		*(int *)shmadder = count;
		sem_v(semid);     //加一操作
	}

	shmdt(shmadder);

	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值