信号量

5 篇文章 0 订阅

临界资源:同一时刻只允许一个进程访问的资源
临界区:访问临界资源的代码段
当我们编写的程序使用了线程时,不管是运行在多用户系统上、多进程系统上,还是运行在多用户多进程系统上。我们通常会发现,程序中存在着一部分临界代码,我们需要确保只有一个进程(或只有一个执行进程)可以进去这个临界代码并拥有对资源独占式的访问权。
信号量:是一个特殊的变量,只允许对它等待(wait)和发送信号(signal)这两种操作。因为在Linux变成中,“等待”和“发送信号”都已具有特殊的含义,所以我们将用原先定义的符号来表示这两种操作。
p(信号量变量):用于等待。如果信号量变量sv大于0,就给它减去1,如果等于0,就挂起该进程的执行。
v(信号量变量):同于发送信号。如有其他进程因等待sv而被挂起,就让他恢复运行,如果没有进程因等待sv而被挂起,就给它加1。
信号量函数的定义如下:

#include<sys/sem.h>
int semctl(int sem_id,int sem_num,int command,...);
int semget(key_t key,int num_sems,int sem_flags);
int semop(int sem_id,struct sembuf *sem_ops,size_t num_sem_op);

接下来完成定义一个信号量进行p,v操作使得两个进程A,B同时运行轮番访问临界资源,进而输出为ABABAB…
sem.h:

//sem.h
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<sys/sem.h>
union semum
{
	int val;
};
void sem_init();
void sem_p();
void sem_v();
void sem_destroy();

sem.c:

//sem.c
#include"main.h"
static int semid=-1;
void sem_init()
{
	semid=semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);
	if(semid==-1)
	{
		semid=semget((key_t)1234,1,0600);
		if(semid==-1)
		{
			perror("semget error");
			return ;
		}	
		else
		{
			union semum a;
			a.val=1;
			if(semctl(semid,0,SETVAL,a)==-1);
			{
				perror("semctl error");
			}
		}
	}
}
void sem_p()
{
	struct sembuf buf;
	buf.sem_num=0;
	buf.sem_op=-1;//p
	buf.sem_flg=SEM_UNDO;
	if(semop(semid,&buf,1)==-1)
	{
		perror("semop p error");
	}
}
void sem_v()
{
	struct sembuf buf;
	buf.sem_num = 0;
	buf.sem_op = 1;//v
	buf.sem_flg = SEM_UNDO;

	if ( semop(semid,&buf,1) == -1 )
	{
		perror("semop p error");
	}
}
void sem_destroy()
{
	if ( semctl(semid,0,IPC_RMID) == -1 )
	{
		perror("semctl del error");
	}
}

a.c:

//a.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include "sem.h"
int main()
{
	sem_init();
	int i = 0;
	for(; i < 5; i++ )
	{
		sem_p();
		printf("A");
		fflush(stdout);
		int n = rand() % 3;
		sleep(n);
		printf("A");
		fflush(stdout);
		sem_v();
		n = rand() % 3;
		sleep(n);
	}
	sleep(10);
	sem_destroy();
}

b.c:

//b.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
int main()
{
	sem_init();
	int i = 0;
	for(; i < 5; i++ )
	{
		sem_p();
		printf("B");
		fflush(stdout);
		int n = rand() % 3;
		sleep(n);
		printf("B");
		fflush(stdout);
		sem_v();
		n = rand() % 3;
		sleep(n);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值