多线程编程之信号量

一.信号量(semaphore)

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

semaphore和mutex类似,表示可用资源的数量,和mutex不同的是这个数量可以大于1。

也就是说,当信号量描述的资源数目是1时,此时的信号量和互斥锁相同。

下面所讲的是POSIX semaphore库函数,这种信号不仅可用于同一进程的线程间同步,也可用于不同进程间的同步。

所用的函数如下:

#include<semaphore.h>

int sem_init(sem_t *sem,int pshared,unsigned int value);

int sem_wait(sem_t *sem);

int sem_trywait(sem_t *sem);

int sem_post(sem_t *sem);

int sem_destroy(sem_t *sem);

semaphore变量的类型是sem_t,sem_init()初始化一个semaphore变量,value参数表示可用资源的数量,pshared参数为0表示信号量用于同一进程的线程同步。

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

二.基于固定大小的环形队列来实现生产者消费者模型

  1 #include<stdio.h>
  2 #include<semaphore.h>
  3 #include<pthread.h>
  4 #define _SIZE_ 20
  5 sem_t blank;
  6 sem_t data;
  7 pthread_mutex_t lock1;
  8 pthread_mutex_t lock2;
  9 int buf[_SIZE_];
 10 void *product(void *arg)
 11 {
 12         int i=0;
 13         int count=0;
 14         while(1)
 15         {
 16                 //pthread_mutex_lock(&lock1);   //把生产者之间的锁加在信号量外面(不可取)
 17                 sem_wait(&blank);
 18                 pthread_mutex_lock(&lock1);    //把生产者之间的锁加在信号量的里面(可取)
 19                 buf[i]=count++;
 20                 sleep(rand()%3);
 21                 pthread_mutex_unlock(&lock1);
 22                 sem_post(&data);
 23                 i++;
 24                 i%=_SIZE_;
 25                 //pthread_mutex_unlock(&lock1);
 26         }
 27 }
 28 void *consumer(void *arg)
 29 {
 30         int i=0;
 31         int count=0;
 32         while(1)
 33         {
 34                 //pthread_mutex_lock(&lock2);   //把消费者之间的锁加在信号量的外面(不可取)
 35                 sem_wait(&data);
 36                 pthread_mutex_lock(&lock2);    //把消费者之间的锁加在信号量的里面(可取)
 37                 count=buf[i];
 38                 printf("consumer:%d,consumer data:%d\n",(int)arg,count);
 39                 pthread_mutex_unlock(&lock2);
 40                 sem_post(&blank);
 41                 i++;
 42                 i%=_SIZE_;
 43                 //pthread_mutex_unlock(&lock2);
 44         }
 45 }
 46 int main()
 47 {
 48         pthread_mutex_init(&lock1,NULL);
 49         pthread_mutex_init(&lock2,NULL);
 50         pthread_t tid1,tid2,tid3,tid4;
 51         sem_init(&blank,0,_SIZE_);
 52         sem_init(&data,0,0);
 53         pthread_create(&tid1,NULL,product,(void*)1);
 54         pthread_create(&tid2,NULL,product,(void*)2);
 55         pthread_create(&tid3,NULL,consumer,(void*)3);
 56         pthread_create(&tid4,NULL,consumer,(void*)4);
 57         pthread_join(tid1,NULL);
 58         pthread_join(tid2,NULL);
 59         pthread_join(tid3,NULL);
 60         pthread_join(tid4,NULL);
 61         pthread_mutex_destroy(&lock1);
 62         pthread_mutex_destroy(&lock2);
 63         sem_destroy(&blank);
 64         sem_destroy(&data);
 65         return 0;
 66 }

运行结果:(1)把锁加在信号量的内部:

(2)把锁加在信号量的外部

时间: 2024-10-18 15:18:35

多线程编程之信号量的相关文章

【C/C++多线程编程之七】pthread信号量

多线程编程之信号量 Pthread是 POSIX threads 的简称,是POSIX的线程标准. 互斥量用来处理一个共享资源的同步访问问题,当有多个共享资源时,就需要用到信号量机制.          信号量机制用于保证两个或多个共享资源被线程协调地同步使用,信号量的值对应当前可用资源的数量.          1.信号量(samaphore):         信号量机制通过信号量的值控制可用资源的数量.线程访问共享资源前,需要申请获取一个信号量,如果信号量为0,说明当前无可用的资源,线程无

Linux多线程编程-信号量

在Linux中,信号量API有两组,一组是多进程编程中的System V IPC信号量:另外一组是我们要讨论的POSIX信号量.这两组接口类似,但不保证互换.POSIX信号量函数都已sem_开头,并不像大多数线程函数那样以pthread_开头,常用的有以下5个: #include <semaphore.h> int sem_init(sem_t* sem, int pshared, unsigned int value); int sem_destroy(sem_t *sem); int se

多线程编程基础知识

多线程编程基础知识 http://www.cnblogs.com/cy163/archive/2006/11/02/547428.html 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.因此掌握

Java多线程编程— 概念以及经常使用控制

多线程能满足程序猿编写很有效率的程序来达到充分利用CPU的目的,由于CPU的空暇时间可以保持在最低限度.有效利用多线程的关键是理解程序是并发运行而不是串行运行的.比如:程序中有两个子系统须要并发运行,这时候就须要利用多线程编程. 线程的运行中须要使用计算机的内存资源和CPU. 一.    进程与线程的概念 这两者的概念,这里仅仅给出自己狭隘的理解: 进程:进程是一个独立的活动的实体,是系统资源分配的基本单元. 它能够申请和拥有系统资源. 每一个进程都具有独立的代码和数据空间(进程上下文). 进程

java多线程编程

一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序要简单,但其他的一般都更复杂.在多线程访问共享数据的时候,这部分代码需要特别的注意.线程之间的交互往往非常复杂.不正确的线程同步产生的错误非常难以被发现,并且重现以修复. 2)上下文切换的开销当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指

Java多线程编程总结

Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换  Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠  Java线程:线程的调度-优先级 Java线程:线程的调度-让步 Java线程:线程的调度-合并 Java线程:线程的调度-守护线程 Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块  Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线

C#多线程编程

C#多线程编程 一.使用线程的理由 1.可以使用线程将代码同其他代码隔离,提高应用程序的可靠性. 2.可以使用线程来简化编码. 3.可以使用线程来实现并发执行. 二.基本知识 1.进程与线程:进程作为操作系统执行程序的基本单位,拥有应用程序的资源,进程包含线程,进程的资源被线程共享,线程不拥有资源. 2.前台线程和后台线程:通过Thread类新建线程默认为前台线程.当所有前台线程关闭时,所有的后台线程也会被直接终止,不会抛出异常. 3.挂起(Suspend)和唤醒(Resume):由于线程的执行

线程同步-iOS多线程编程指南(四)-08-多线程

首页 编程指南 Grand Central Dispatch 基本概念 多核心的性能 Dispatch Sources 完结 外传:dispatch_once(上) Block非官方编程指南 基础 内存管理 揭开神秘面纱(上) 揭开神秘面纱(下) iOS多线程编程指南 关于多线程编程 线程管理 Run Loop 线程同步 附录 Core Animation编程指南 Core Animation简介 基本概念 渲染架构 几何变换 查看目录 中文手册/API ASIHTTPRequest Openg

VC++多线程编程-线程间的通信和线程同步

引用:http://blog.csdn.net/zjc0888/article/details/7372258 线程间通讯 一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信.这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的,下面将进行说明. 使用全局变量进行通信 由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简单的一种方法是使用全局变量.对于标准类型