Linux——信号量

临界资源:同一时刻只允许一个进程访问资源
临界区:访问临界资源的代码段。

获取资源则-1, p操作,会阻塞
释放资源则+1,v操作,不会阻塞
p,v操作皆为原子操作,不会被打断

ipcs -s查看信号量
ipcrm -s +地址 删除信号量

                     打印
                 临界资源
                      0/1
  A                                             B 
   p()                                        p()      阻塞
  for(i=0;i<4;i++)                 for(i=0;i<6;i++)
  printf(A)                            printf(B)
  printf(A)                            printf(B)
  v()                                      v()
  此过程称为同步。

信号量的封装

//创建文件sem.h存放函数声明
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<sys/sem.h>

union semun
{
	int val;
};
void sem_init();//创建或获取信号量
void sem_p();//P操作
void sem_v();//V操作
void sem_destroy();//销毁操作

//直接调用sem.h函数
#include"sem.h"

 static int semid = -1;//全局变量,由于后面int返回值为地址,所以必须将初始值定为-1;static是只在当前文件中有效。

void sem_init()
//考虑是否已有信号量,若无则创建,若有则error获取已有信号量。
{
     //create init 1
     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 semun 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;
	buf.sem_flg=SEM_UNDO;
	if(semop(semid,&buf,1)==-1)
	{
		perror("semop error");
	}
}

void sem_v()
{
	struct sembuf buf;
	buf.sem_num=0;
	buf.sem_op=1;
	buf.sem_flg=SEM_UNDO;
	if(semop(semid,&buf,1)==-1)
	{
		perror("semop error");
	}
}

void sem_destroy()
{
	if(semctl(semid,0,IPC_RMID)==-1)
	{
		perro("semtcl error");
	}
}

信号量的使用

//打印A
#include"sem.h"

int main()
{
	sem_init();
	int i=0;
	for(;i<5;i++)
	{
		sem_p();//P操作-1
		printf("A");
		fflush(stdout);
		int n=rand()%3;//随机值对三取余
		sleep(n);
		printf("A");
		fflush(stdout);
		sem_v();//V操作+1
		n=rand()%3;
		sleep(n);
	}
}


//打印B
#include "sem.h"

int main()
{
	sem_init();
	int i=0;
	for(;i<5:i++)
	{
		sem_p();//p操作
		printf("B");
		fflush(stdout);//刷新标准输入缓冲区
		int n=rand()%3;
		sleep(n);//睡眠随机时间
		printf("B");
		fflush(stdout);
		sem_v();//v操作
		n=rand()%3;
		sleep(n);
	}
	sem_destroy();//销毁,只能销毁一次
	exit();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有头发的小小猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值