Linux进程间通讯 | 信号量、共享内存、消息队列


前言

进程间通信的一种方式:信号量


提示:以下是本篇文章正文内容,下面案例可供参考

一、临界资源与临界区

同一时间段只允许一个进程或线程访问的资源叫做临界资源。
访问临界资源的代码段叫临界区。

二、信号量

信号量是一个特殊的变量,一般取正数值。它的值代表允许访问的资源数目,获取资源时,需要对信号量的值进行原子减一,该操作被称为 P 操作当信号量值为 0 时,代表没有资源可用,P 操作会阻塞。释放资源时,需要对信号量的值进行原子加一,该操作被称为 V操作。信号量主要用来同步程。信号量的值如果只取 0,1,将其称为二值信号量。如果信号量的值大于 1,则称之为计数信号量

三、信号量使用方法

1.常用接口

int semget(key_t key, int nsems, int semflg);//创建或获取信号量

int semop(int semid, struct sembuf *sops, unsigned nsops);//信号量的加减操作

int semctl(int semid, int semnum, int cmd, …);//控制信号量

2.使用示例

代码如下(示例):

sem.c//
static int semid;//初始化信号量
void init_sem
{
	semid=semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);
	if(semid==-1)//证明1234已经创建
	{
		semid=semget((key_t)1234,1,IPC_CREAT|0600)//直接获取semid
		{
			if(semid==-1)//获取失败
			{
				printf("semget err\n");
				return;
			}	
		}
	}
	else//1234没有被创建
	{
		union semun a;
		a.val=1;
		if(semctl(semid,0,SETVAL,a)==-1)//初始化信号量
		{
			printf("setval err\n");
			return;
		}			
	}
}
int sem_p//减1操作
{
	struct sembuf buf;
	buf.sem_num=0;
	buf.sem_op=-1;
	buf.sem_flg=SEM_UNDO;
	if(semop(semid,&buf,1)==-1)
	{
		printf("sem_p err\n");
		return -1;
	}
	return 0;
}
int sem_v//加1操作
{
	struct sembuf buf;
	buf.sem_num=0;
	buf.sem_op=1;
	buf.sem_flg=SEM_UNDO;
	if(semop(semid,&buf,1)==-1)
	{
		printf("sem_v err\n");
		return -1;
	}
	return 0;
}
void destroy_sem()//销毁信号量
{
	if(semctl(semid,0,IPC_RMID)==-1)
	{
		printf("destroy err\n");
	}
}
a.c//打印A
int main()
{
	sem_init();
	for(int i=0;i<5;++i)
	{
		sem_p();
		printf("A");
		fflush(stdout);
		int n=rand()%3;
		sleep(n);
		printf("A");//打印完第二次A证明a.c任务完成
		fflush(stdout);
		sem_v();
		sleep(rand()%3);
	}
	
	sleep(10);//让A最后结束
	destroy_sem();//销毁信号
}

b.c//打印B
int main()
{
	sem_init();
	for(int i=0;i<5;++i)
	{
		sem_p();
		printf("B");
		fflush(stdout);
		int n=rand()%3;
		sleep(n);
		printf("B");//打印完第二次B证明b.c任务完成
		fflush(stdout);
		sem_v();
		sleep(rand()%3);
	}
	
	
}

2.输出结果

在这里插入图片描述

四、共享内存

1.什么是共享内存

共享内存为多个进程之间共享和传递数据提供了一种有效的方式。共享内存是先在物理内存上申请一块空间,多个进程可以将其映射到自己的虚拟地址空间中。所有进程都可以访问共享内存中的地址,就好像它们是由 malloc 分配的一样。如果某个进程向共享内存写入了数据,所做的改动将立刻被可以访问同一段共享内存的任何其他进程看到。由于它并未提供同步机制,所以我们通常需要用其他的机制来同步对共享内存的访问。
在这里插入图片描述

2.代码示例

在这里插入图片描述
输出:
在这里插入图片描述

五、消息队列

在这里插入图片描述
创建一个消息队列,可以有多个程序进行消息的添加,另外多个程序进行消息的读取。消息要有具体的编号,这样接受的程序会根据编号接受相应的消息。
消息队列也是创建在内存中。当接受消息的程序将接受消息类型设置为0时,表示接受程序不按消息类型进行接受,即接受所有类型的消息。

总结

信号量可以对两个进程进行控制,使其按照一定的顺序执行。
ipcs 这个指令可以查看当前的共享内存,信号量,消息队列的内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值