操作系统-信号量机制

信号量机制

整型信号量

用一个整数型的变量作为信号量,用来表示股系统中某种资源的数量。
与普通整数变量的区别:对信号量的操作只有三种,
初始化,P操作,V操作。

P操作:相当于wait原语,进入区
V操作:signal原语,相当于退出区。

大体实现:
wait()方法一气呵成,避免并发导致的问题。
但是不满足“让权等待原则”,进程会处于忙等的状态。

int S=1;
void wait(int S){ //wait 原语,相当于“进入区”
    while(S<=0); //如果资源数不够,就一直循环等待
    S=S-1;  //如果资源数够,就占用一个资源
}

void signal (int S){ //signal 原语,相当于“退出区”
    S=S+1; //使用完资源后,释放资源
}

记录型信号量

/记录型信号量的定义/

typedef struct{
    int value; //剩余资源数
    Struct process *L;  //等待队列

} semaphore;

/*某进程需要使用资源时,通过wait原语申请*/
void wait(semaphore S){
    S.value--;
    if(S.value<0){
        block (S.L);
    }

}

// 进程使用完资源后,通过signal原语释放资源
void signal(semaphore S){
        S.value++;
        if(S.value<=0){
            wakeup(S.L)}
}

S.value的初始值表示系统中某种资源的数目。 对信号量S的一次P操作意味着进程请求一个单位的该类资源,因此需要执行S.value--,表示资源数减1,当S.value<0时表示该类资源已经被分配完毕,因此使申请资源的进程调用block原语进行自我阻塞(运行态->阻塞态),主动放弃处理机,并插入该类资源等代队列中,该实现遵循了让权等待原则,不会出现忙等现象。 V操作中,一定是先S.value++,如果加一后,S.value仍然大于等于0,表示依然有进程在等待该类资源。 可能需要执行wakeup原语。 记录型信号量实现系统资源的申请和释放,还可以实现进程的互斥和同步。

用信号量实现进程互斥,同步、前驱关系

信号量机制实现进程互斥

1、分析并发进程的关键活动,滑动临界区
2、设置互斥信号量mutex,初始值为1
3、在临界区之前执行P
4、在临界区之后执行V
注意:对于不同的临界资源需要设置不同的互斥信号量
P,V操作必须成对出现。缺少P操作不能保证进程互斥访问资源,缺少V操作,导致资源永不被释放,等待的进程永远不被唤醒。

信号量实现进程同步

分析问题,找出哪里需要实现“一前一后的”同步关系
设置同步信号量,初始值为0
在“前操作”之后执行V操作
在“后操作之前”执行P操作。

信号量实现进程的前驱关系

分析问题划出前驱图,把每一个前驱关系都看成一个同步问题
为每一对前去关系设置同步信号量,初始值为0
在“前操作”之后执行V操作
在“后操作之前”执行P操作。

猜你喜欢

转载自blog.csdn.net/qq_43672652/article/details/107677680