当前位置:首页 > 操作系统 > Linux

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/* 将信号量定义为全局变量,方便多个线程共享 */  7sem_t sem;
  8  9/* 线程1和线程2的公用命令 */ 10int gCmd = 0;
 11 12/* 同步线程1和线程2的全局变量 */ 13staticint gIsExecFlag = 0;
 14 15/* 定义线程pthread1 */ 16staticvoid * pthread1(void *arg)       
 17{    
 18/* 线程pthread1开始运行 */ 19     printf("pthread1 start!n");
 20 21while(1)
 22    {
 23/* 等待没有命令正在执行 */ 24while(gIsExecFlag);
 25 26/* 更新命令 */ 27         gCmd++;
 28if(gCmd == 10)
 29        {
 30/* 释放信号量 */ 31             sem_post(&sem);
 32 33/* 发送命令结束 */ 34return NULL;
 35        }
 36 37/* 释放信号量 */ 38         sem_post(&sem);
 39 40/* 等待线程2执行命令 */ 41         sleep(1);
 42    }
 43}
 44 45/* 定义线程pthread2 */ 46staticvoid * pthread2(void *arg)       
 47{
 48int tmp;
 49 50/* 线程pthread2开始运行 */ 51     printf("pthread2 start!n");
 52 53while(1)
 54    {
 55if (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 73if(gCmd == 10){
 74/* 命令执行结束 */ 75return NULL;
 76        }
 77    }
 78}
 79 80/* main函数 */ 81int main(int agrc,char* argv[])
 82{
 83    pthread_t tidp1,tidp2;            
 84 85/* 初始化信号量sem */ 86     sem_init(&sem, 0, 0);
 87 88/* 创建线程pthread1 */ 89if ((pthread_create(&tidp1, NULL, pthread1, NULL)) == -1)
 90    {
 91         printf("create error!n");
 92return1;
 93    }
 94 95/* 同步,让线程1先执行 */ 96     usleep(10);
 97 98/* 创建线程pthread2 */ 99if ((pthread_create(&tidp2, NULL, pthread2, NULL)) == -1)
100    {
101         printf("create error!n");
102return1;
103    }
104105/* 等待线程pthread1释放 */106if (pthread_join(tidp1, NULL))                  
107    {
108         printf("thread is not exit...n");
109return -2;
110    }
111112/* 等待线程pthread2释放 */113if (pthread_join(tidp2, NULL))                  
114    {
115         printf("thread is not exit...n");
116return -2;
117    }
118119return0;
120 }

 

 

 

 

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

 

原文:http://www.cnblogs.com/amanlikethis/p/5540364.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!

相关教程推荐

其他课程推荐