一、Semaphore(信号量)

    Mutex变量是非0即1的,可看作一种资源的可用数量,初始化时Mutex是1,表示有一个可用资源, 加锁时获得该资源,将Mutex减到0,表示不再有可用资源,解锁时释放该资源,将Mutex重新加到1,表示又有了一个可用资源。

     信号量(Semaphore)和Mutex类似,表示可用资源的数量,和Mutex不同的是这个数量可以大于1。

即,如果信号量描述的资源数目是1时,此时的信号量和互斥锁相同!

本次使用的是POSIX semaphore库函数,这种信号量不仅可以于同一进程的线程间同步,也可以用于不同进程间的同步。

使用如下:

wKioL1cceRvBmhyAAAAZQGewxwU501.jpg

wKiom1cceFWg_zmrAAAitfUO9f4274.jpg

wKioL1cceRvTkNJ9AAAJA9mAj2w968.jpg

wKiom1cceFWyE3nMAAAKWIpsHgI023.jpg

semaphore变量的类型为sem_t,sem_init()初始化一个semaphore变量,value参数表示可用资源的数量,pshared参数为0表示信号量适用于同一进程的线程间同步。在使用完完semaphore变量之后应该调用sem_destroy()释放与semaphore相关的资源。

调用sem_wait()可以获得资源(P操作),使semaphore的值减1,如果调用sem_wait()时semaphore的值已 经是0,则挂起等待。如果不希望挂起等待,可以调用sem_trywait() 。调sem_post() 可以释放资源(V操作),使semaphore 的值加1,同时唤醒挂起等待的线程。 

二、实现生产者--消费者问题

(1).本例中主要使用环形buf与信号量来实现单消费者,单生产者,其环形buf的实现主要用数组下标模环形buf的大小20。

对于生产者而言:不能在生产速度上把消费者套圈。

对于消费者而言:其消费速度不能超过生产者。

本例中主要实现:当生产者所需空格数为0,便挂起等待消费者消费 。当消费者消费数据为0,便挂起等待生产者生产。其生产者空格初始值为20,其消费者数据初始值为0。代码如下:

wKiom1cccKuACBHyAACbjUcnL9U442.jpg

wKioL1cccXKjLs3uAACMMy2hZr4931.jpg

wKiom1cccK2iIIdVAAAu-dpmQc0269.jpg

运行结果:

wKiom1cccK2TGThJAACzvfEJmvc520.jpg

(2).多生产者,多消费者,修改代码如下,需要分别对生产者,消费者加锁。

wKiom1ccdTGxrstcAABX9SVd9LY290.jpg

wKioL1ccdfiC3YctAABSNVxblyE024.jpg

运行结果如下:

wKiom1ccdTLCx_ViAACmMJwzN8k692.jpg

总结:对于多生产者多消费者,要在其信号量操作内加锁,而不在外部,因为信号量的操作是原子的。并且效率更高。

信号量不是加锁,主要是用来同步的。但是也可以用信号量操作实现加锁。