信号量

                                       1.进程互斥
1>进程互斥的概念

    由于各进程要求共享资源,而且有的资源需要互斥使用,因此在这些进程之间要竞争使用这些资源,这种关系就称为进程的互斥

2>临界资源(互斥资源)

    系统中某些资源每一次只允许一个进程使用,这些资源就称为临界资源或者互斥资源

3>临界区

    在进程中涉及到互斥资源的程序段称为临界区


                                2.进程间的同步

1>进程同步的概念

    多个进程需要相互配合完成一项任务的这种关系称为进程同步

进程同步的案例

                  

                                    3.信号量和原语
    >>信号量的本质:是一个计数器

    >>信号量:互斥:P、V在同一个进程中

                      同步:P、V在不同进程中

    >>信号量值的含义: S表示可用资源的个数

                                S>0  表示有资源可用

                                S=0  表示没有可用资源,也没有等待进程

                                S<0  表示等待队列中

    >>信号量结构体伪代码

struct semaphore {
				int value;
				struct task_struct queue; //等待该信号量所控制的资源的队列
		};
    >>原语:整个操作要么都做,要么都不做
    p(struct semaphore s)
		{
			s.vlue--;
			if( s.vlue < 0 ){
				将进程置成阻塞态
				放入等待队列
			}
		}
		v(struct semaphore s){
			s.value++;
			if( s.value <= 0 ){
				唤醒某个等待该资源的进程 
			}
		}                              
                                    4.信号量集
1.创建或打开信号量
semget( 
			key_t key,
			int nsems, //信号量集中信号量的个数
			int flg); //IPC_CREAT|0644  0

2.设置初值

union semun{ int val; };
	
	union semun su;
	su.val = 1;
				

3.查看信号量的值

int semctl(int id,
				int semnum, // 信号量集中的第几个信号量
				int cmd); //GETVAL
				
		返回值:信号量的计数值

4.PV操作

int semop(int id,
				struct sembuf *sb, //数组
				int len);
		struct sembuf{
			int sem_num; // 第一个信号量
			int sem_op; // P -1, V +1
			int sem_flag; //0
		}

代码测试:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/ipc.h>
  5 #include <sys/sem.h>
  6 #include <string.h>
  7 
  8 int id;
  9 
 10 void p( void )
 11 {
 12     struct sembuf sb[1] = {0,-1,0};
 13     semop(id, sb, 1);
 14 }
 15 
 16 void v( void )
 17 {
 18     struct sembuf sb[1] = {0,1,0};
 19     semop(id, sb, 1);
 20 }
 21 
 22 void print(char c)
 23 {
 24     int i = 0;
 25     for( i=0; i<10; i++) {
 26         p();
 27         printf("%c", c);
 28         fflush(stdout);
 29         sleep(rand()%3);
 30         printf("%c", c);
 31         fflush(stdout);
 32         v();
 33         sleep(rand()%3);
 34     }
 35 }
 36 
 37 union semun{int val;};
 38 
 39 int main( void )
 40 {
 41     srand(getpid());
 42     id = semget(1234, 1, IPC_CREAT|0600);
 43     union semun su;
 44     su.val = 1;
 45     semctl(id, 0, SETVAL, su);
 46     pid_t pid = fork();
 48     if ( pid == 0 ){
 49         print('O');
 50     } else {
 51         print('X');
 52     }
 53 }

该段代码的功能是: fork,一个父进程,一个子进程,父进程打印“O”,子进程打印"X",随机打印的

运行结果:

[qiong@localhost sem]$ ./a.out
XXOOXXOOXXOOXXOOXXOOXXOOXXXXXXOOOOOOXXOO


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值