linux信号量之进程间同步

概念

linux信号量:允许多个线程同时进入临界区,可以用于进程间的同步。

和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区。

所在头文件:semaphore.h

主要函数

  • 初始化函数

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

      sem:要初始化的信号量

      pshared:此信号量是在进程间共享还是线程间共享

      value:信号量的初始值

  • 删除函数

      int sem_destroy(sem_t *sem)

      sem:要销毁的信号量

      注意:只有用sem_init初始化的信号量才能用sem_destroy销毁

  • 等待信号量函数

      int sem_wait(sem_t *sem)

      功能:等待信号量,如果信号量的值大于0,将信号量的值减1,立即返回;

         如果信号量的值为0,则线程阻塞。相当于P操作。

         成功返回0,失败返回-1。

  • 释放信号量

      int sem_post(sem_t *sem)

      功能:释放信号量,让信号量的值加1。相当于V操作。

例程

例程描述:

  该例程的主要目的,在于模仿异步执行命令。所谓异步执行命令,就是说一个进程用于接收发送命令,另外一个进程用于实际执行命令。实际工程中,经常会遇到有许多种命令要在一个进程中得到解析并执行,有些命令耗时短,可以在此进程中完成;但是,有些命令耗时长,如果也放在这个进程中,则影响该进程接收(其他命令)。所以,此时可以考虑用异步执行的方案,将耗时短的命令,就放在接收解析进程中;而将耗时长的命令,则用异步执行的方案,将接收与实际执行分离,以避免接收受到严重阻塞。

本例程中,用主线程创建了两个子线程pthread1和pthread2,其中线程pthread1用于产生和发送命令,而线程pthread2用于实际执行命令。

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<pthread.h>
  4 #include <semaphore.h>
  5
  6 /* 将信号量定义为全局变量,方便多个线程共享 */
  7 sem_t sem;
  8
  9 /* 线程1和线程2的公用命令 */
 10 int gCmd = 0;
 11
 12 /* 同步线程1和线程2的全局变量 */
 13 static int gIsExecFlag = 0;
 14
 15 /* 定义线程pthread1 */
 16 static void * pthread1(void *arg)
 17 {
 18     /* 线程pthread1开始运行 */
 19     printf("pthread1 start!\n");
 20
 21     while(1)
 22     {
 23         /* 等待没有命令正在执行 */
 24         while(gIsExecFlag);
 25
 26         /* 更新命令 */
 27         gCmd++;
 28         if(gCmd == 10)
 29         {
 30             /* 释放信号量 */
 31             sem_post(&sem);
 32
 33             /* 发送命令结束 */
 34             return NULL;
 35         }
 36
 37         /* 释放信号量 */
 38         sem_post(&sem);
 39
 40         /* 等待线程2执行命令 */
 41         sleep(1);
 42     }
 43 }
 44
 45 /* 定义线程pthread2 */
 46 static void * pthread2(void *arg)
 47 {
 48     int tmp;
 49
 50     /* 线程pthread2开始运行 */
 51     printf("pthread2 start!\n");
 52
 53     while(1)
 54     {
 55         if (sem_wait(&sem) != 0)
 56         {
 57             printf("Error!\n");
 58         }
 59
 60         /* 正在执行的标志置1 */
 61         gIsExecFlag = 1;
 62
 63         /* 线程2接受来自线程1的命令,并打印 */
 64         tmp = gCmd;
 65         printf("now execute the cmd,and the code of cmd is %d.\n", tmp);
 66
 67         /* 执行命令需要时间:3s */
 68         sleep(3);
 69
 70         /* 正在执行的标志清0 */
 71         gIsExecFlag = 0;
 72
 73         if(gCmd == 10){
 74             /* 命令执行结束 */
 75             return NULL;
 76         }
 77     }
 78 }
 79
 80 /* main函数 */
 81 int main(int agrc,char* argv[])
 82 {
 83     pthread_t tidp1,tidp2;
 84
 85     /* 初始化信号量sem */
 86     sem_init(&sem, 0, 0);
 87
 88     /* 创建线程pthread1 */
 89     if ((pthread_create(&tidp1, NULL, pthread1, NULL)) == -1)
 90     {
 91         printf("create error!\n");
 92         return 1;
 93     }
 94
 95     /* 同步,让线程1先执行 */
 96     usleep(10);
 97
 98     /* 创建线程pthread2 */
 99     if ((pthread_create(&tidp2, NULL, pthread2, NULL)) == -1)
100     {
101         printf("create error!\n");
102         return 1;
103     }
104
105     /* 等待线程pthread1释放 */
106     if (pthread_join(tidp1, NULL))
107     {
108         printf("thread is not exit...\n");
109         return -2;
110     }
111
112     /* 等待线程pthread2释放 */
113     if (pthread_join(tidp2, NULL))
114     {
115         printf("thread is not exit...\n");
116         return -2;
117     }
118
119     return 0;
120 }

参考资料:Linux线程的信号量同步

时间: 2024-10-25 19:42:50

linux信号量之进程间同步的相关文章

一起talk C栗子吧(第一百回:C语言实例--使用信号量进行进程间同步与相互排斥一)

各位看官们.大家好,上一回中咱们说的是进程间同步与相互排斥的样例,这一回咱们说的样例是:使用信号量进行进程间同步与相互排斥. 闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,信号量是由著名计算机科学家迪杰斯特拉(Dijkstra)提出的一种概念,专门用来解决进程间同步与相互排斥.在他提出的概念中信号量是一个非负整数值. 信号量的操作仅仅能有两种原子操作: 等待信号; 发送信号. "什么是原子操作呢?"台下有看官在提问.原子操作就是指某个动作在运行时不能被其他动作中断,它会一

Linux进程间通信与线程间同步详解(全面详细)

引用:http://community.csdn.net/Expert/TopicView3.asp?id=4374496linux下进程间通信的几种主要手段简介: 1. 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信:   2. 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身

Linux/UNIX之进程间的通信(2)

进程间的通信(2) 有三种IPC我们称为XSI IPC,即消息队列.信号量以及共享存储器,它们之间有很多相似之处. 标识符和键 每个内核的IPC结构(消息队列.信号量或共享存储段)都用一个非负整数的标识符加以引用.例如,为了对一个消息队列发送或取消息,只需要知道其队列标识符.与文件描述符不同,IPC标识符不是小的整数.当一个IPC结构被创建,以后被删除时,与这种结果相关的标识符连续加1,知道达到一个整型数的最大值,然后又回到0. 标识符是IPC对象的内部名.为使多个合作进程能够在同一IPC对象上

进程间同步(1)&mdash;&mdash;条件变量和互斥量

1. 概述 条件变量和互斥量是最基本的同步形式,总是用于同步同一个进程的各个线程间同步. 当把条件变量或互斥量放在共享内存区时,可用于进程间同步. 同样的情况还有读写锁,它们都是随进程的持续性.   2.互斥锁 互斥锁指代相互排斥,用于保护临界区.多个线程和多个进程分享的共享数据. 静态初始化:static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 动态初始化:互斥锁是动态分配的,pthread_mutex_init(&mutex);初始

一个进程间同步和通讯的 C# 框架

转自原文 一个进程间同步和通讯的 C# 框架 threadmsg_demo.zip ~ 41KB    下载 threadmsg_src.zip ~ 65KB    下载 0.背景简介 微软在 .NET 框架中提供了多种实用的线程同步手段,其中包括 monitor 类及 reader-writer锁.但跨进程的同步方法还是非常欠缺.另外,目前也没有方便的线程间及进程间传递消息的方法.例如C/S和SOA,又或者生产者/消费者模式中就常常需要传递消息.为此我编写了一个独立完整的框架,实现了跨线程和跨

进程间同步---system v ipc 对象信号灯集

一.信号灯简介 Linux支持System V的信号灯(semaphore),是一种进程间通信的方式,只不过它和管道.FIFO或者共享内存不一样,信号灯主要用于同步或者互斥对共享资源的访问,它的发明来源于火车运行系统中的"信号灯",利用信号灯可以实现"PV"操作这种进程间同步进制.P操作时获得资源,将信号灯的值减1,如果结果不为负则执行完毕,进程获得资源,否则进程睡眠以等待的进程释放;V操作则是释放资源,给信号灯的值加1, 唤醒一个因执行P操作而等待的进程. 二.信

用信号量解决进程的同步与互斥探讨【持续更新】

现代操作系统采用多道程序设计机制,多个进程可以并发执行,CPU在进程之间来回切换,共享某些资源,提高了资源的利用率,但这也使得处理并发执行的多个进程之间的冲突和相互制约关系成为了一道难题.如果对并发进程的调度不当,则可能会出现运行结果与切换时间有关的情况,令结果不可再现,影响系统的效率和正确性,严重时还会使系统直接崩溃.就比如你只有一台打印机,有两个进程都需要打印文件,如果直接让他们简单地并发访问打印机,那么你很可能什么都打印不出来或者打印的文件是...anyway,我们需要增加一些机制来控制并

操作系统--进程间同步

1.1 进程同步机制 (1) 原子操作:所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它是最小的执行单位,不可能有比它更小的执行单位.原子操作需要硬件的支持,因此是架构相关的. (2) 信号量:信号量sem是一整数,当它的值大于0时,表示当前可用资源的数量:当它的值小于0时,其绝对值表示等待使用该资源的进程个数.注意,信号量的值仅能由PV操作来改变. P(S):(1)将信号量S的值减1,即S=S-1 (2)如果S>=0,则该进程继续执行:否则该进程置为等待状态,排入

linux 进程间同步互斥

参考链接: https://www.oschina.net/code/snippet_237505_8646 http://www.cnblogs.com/xilentz/archive/2012/11/13/2767317.html 互斥: http://blog.csdn.net/szkbsgy/article/details/50458641