1、信号量是什么
信号量是一种进程同步工具,可以同步并发进程,相较于互斥锁,可以解决更多类型的同步问题(同步即是指进程之间有序执行,而异步是指随机执行)。
2、信号量如何实现
信号量是一个整数值,除了初始化其他时间内只能通过PV操作改变其值。信号量通过两个操作来实现,分别命名为P操作和V操作。其中P操作是指等待(wait operation),V操作是指信号数量增加(signal operation)。这两种操作均为原子操作。
p(s){
while(s<=0)
do nothing;
s--;
}
v(s){
s++;
}
3、信号量不同取值的应用场景
(1)信号量取值为0或1用于实现互斥锁的作用
semaphore mutex = 1;
process pi{
p(mutex);
critical section
v(mutex);
}
(2)信号量取值为大于1,一般信号量可以取任意值,可以控制并发进程对共享资源的访问,用于表示可控资源的数量。
semaphore road = 2;
process Carsi{
p(road);
pass the fork in the road
v(road);
}
(3)初始值设置为0则用于进程同步。
4、信号量实现同步实例:司机售票员
司机:启动车辆->正常行车->到站停车
售票员:关车门->售票->开车门
规则:司机要等车门关闭才能开车 售票员要等车停下才能开门
//
// driver_conductor.c
//
//
// Created by YIN on 2021/5/16.
//
#include "driver_conductor.h"
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <dispatch/dispatch.h>
dispatch_semaphore_t d;
dispatch_semaphore_t c;
/*
司机:启动车辆;正常行车;到站停车。
售票:关车门;售票;开车门。
*/
void* driver(void* args)
{
dispatch_semaphore_wait(d, DISPATCH_TIME_FOREVER);
printf("Start the vehicle\n");
printf("Normal driving\n");
printf("Stop at the station\n");
dispatch_semaphore_signal(c);
}
void* conductor(void* args)
{
printf("Close the car door\n");
dispatch_semaphore_signal(d);
printf("Ticket sales\n");
dispatch_semaphore_wait(c, DISPATCH_TIME_FOREVER);
printf("Open the car door\n");
}
int main(int argc, char const *argv[])
{
pthread_t pid_driver;
pthread_t pid_conductor;
dispatch_semaphore_t *sem_d = &d;
*sem_d = dispatch_semaphore_create(0);
dispatch_semaphore_t *sem_c = &c;
*sem_c = dispatch_semaphore_create(0);
pthread_create(&pid_driver, NULL, driver, NULL);
pthread_create(&pid_conductor, NULL, conductor, NULL);
pthread_join(pid_driver, NULL);
pthread_join(pid_conductor, NULL);
return 0;
}