信号量及PV原语

操作系统中进程互斥和同步的实现的一个最基本的方方是使用信号量和PV原语。

信号量S的物理意义:当S≥0的时候表示,某个资源可以使用的数量,当S<0的时候,其绝对值表示等待某个资源的进程数。

一般实现进程间的互斥操作的时候S的初始值为1或资源的数目,实现进程间同步的时候S的初始值为0或某个正整数

P操作表示进程申请一个资源,其定义如下:

S=S-1,如果S≥0,那么执行P操作的进程继续执行,否则执行P操作的进程转换成阻塞状态。

V操作表示进程释放一个资源,其定义如下:

S=S+1,如果S≤0,那么从阻塞状态中唤醒一个进程,插入到就绪队列中,执行V操作的进程继续执行,否则执行V操作的进程继续执行,其他进程无影响。

关于PV操作的理解,首先P进程是申请一个资源,那么只需要管自己是否有执行的机会对其他进程没啥影响,如果资源满足执行P操作进程执行的话就执行,否则就阻塞,而V操作是释放一个资源,那么释放完资源,不管现在资源怎样对执行V进程的进程都没有影响,所以执行完V操作之后,该进程总是继续执行,同时V操作可能会对其他进程有所影响,如果执行V操作之后所释放的资源刚好有其他进程在等待,那么就可以从那些等待的进程中唤醒一个插入到就绪队列中了。如果执行P操作后S≥0,那么显然执行P操作(请求资源)之前S>0(有资源可用),所以P进程就可以执行啦,否则就是执行P之前S≤0(没资源可用),所以P进程就被阻塞了。V操作也是一样,如果执行V操作之后S≤0,那么说明执行V之前是S<0(有进程等着用该资源)的,而V操作正好要释放一个这样的资源,所以需要在等待的进程中唤醒一个插入到就绪队列中。这里经常搞混的地方是S=0的时候,按照上述分析如果P操作后S=0,那么P之前S=1,所以有资源可用,。。。如果V操作之后S=0,那么V之前,S=-1,有一个进程在等待,。。。

互斥操作:A、B两个进程对S资源互斥就是他们不能同时使用S资源

S初值为设为1

A:                                          B:

P(S)                                      P(S)

使用S资源                              使用S资源

V(S)                                      V(S) 

同步操作:进程B需要从进程A获得消息后才执行,而这消息,要在A产生消息之后才提供

S初始值设为0

A:                                         B:

产生消息                                P(S)                               

V(S)                                     获得消息                         

                                             

                        

转载于:https://www.cnblogs.com/bewolf/p/4452634.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux,可以使用信号量PV原语操作机制实现进程的同步和互斥。 1. 同步机制:可以使用信号量来实现进程的同步。信号量是一种计数器,它用来控制多个进程对共享资源的访问。在Linux信号量由semget、semop和semctl三个系统调用来完成。 2. 互斥机制:可以使用PV原语操作机制来实现进程的互斥。PV原语操作机制可以实现原子操作,保证多个进程对共享资源的访问是互斥的。在LinuxPV原语操作机制由semaphore.h头文件的sem_init、sem_wait和sem_post三个函数来实现。 下面是一个简单的示例代码: ``` #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <semaphore.h> sem_t sem; // 定义信号量 void *thread_func(void *arg) { sem_wait(&sem); // 等待信号量 printf("Thread %d is running\n", *(int *)arg); sem_post(&sem); // 发送信号量 return NULL; } int main() { sem_init(&sem, 0, 1); // 初始化信号量 pthread_t tid[5]; int i; for (i = 0; i < 5; i++) { int *arg = malloc(sizeof(int)); *arg = i; pthread_create(&tid[i], NULL, thread_func, arg); // 创建线程 } for (i = 0; i < 5; i++) { pthread_join(tid[i], NULL); // 等待线程结束 } sem_destroy(&sem); // 销毁信号量 return 0; } ``` 在上面的示例代码,我们使用了sem_wait和sem_post函数来实现线程的同步。在每个线程,我们使用sem_wait函数等待信号量,当信号量的值为1时,线程可以继续执行。在线程执行完后,我们使用sem_post函数发送信号量,将信号量的值加1,以便其他线程可以继续执行。同时,我们使用sem_init函数初始化信号量,使用sem_destroy函数销毁信号量

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值