Linux信号量线程控制

时间:2022-10-07 18:30:54
线程中互斥锁的使用,达到对共享资源互斥使用。除了使用互斥锁,信号量,也就是操作系统中所提到的PV原语,能达到互斥和同步的效果,这就是今天我们所要讲述的信号量线程控制。

PV原语是对整数计数器信号量sem的操作,一次P操作可使sem减一,而一次V操作可是sem加一。进程(或线程)根据信号量的值来判断是否对公共资源具有访问权限。当信号量的值大于零或等于零的时候,该进程(或线程)具有对公共资源访问的权限,否则,当信号量的值小于时,该进程(或线程)就会被阻塞,直到信号量的值大于或等于一。

1、在LINUX中,实现了POSIX的无名信号量,主要用于线程间的互斥同步,下面将简单介绍一些函数接口:

(1)、sem_init

功能:         用于创建一个信号量,并初始化信号量的值。

头文件:       <semaphore.h>

函数原型:     int sem_init (sem_t* sem, int pshared, unsigned int value);

函数传入值:   sem:信号量。

                   pshared:决定信号量能否在几个进程间共享。由于目前LINUX还没有实现进

                               程间共享信息量,所以这个值只能取0。

函数返回值:   0:成功。

                   -1:失败。

(2)其他函数。

int sem_wait       (sem_t* sem);

int sem_trywait   (sem_t* sem);

int sem_post       (sem_t* sem);

int sem_getvalue (sem_t* sem);

int sem_destroy   (sem_t* sem);

功能:sem_wait和sem_trywait相当于P操作,它们都能将信号量的值减一,两者的区别在

        于若信号量的值小于零时,sem_wait将会阻塞进程,而sem_trywait则会立即返回。

        sem_post相当于V操作,它将信号量的值加一,同时发出唤醒的信号给等待的进程

       (或线程)。

        sem_getvalue 得到信号量的值。

        sem_destroy 摧毁信号量。

函数传入值: sem:信号量。

函数返回值: 同上。

2、函数实现。

[cpp:showcolumns] view plaincopy·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h>    
  2. #include <stdlib.h>    
  3. #include <unistd.h>    
  4. #include <pthread.h>    
  5. #include <semaphore.h>    
  6. #include <errno.h>    
  7.    
  8. #define return_if_fail(p)  /     
  9.         if(!p){printf ("[%s]: func error!", __func__);return NULL;}     
  10.     
  11. typedef struct _PrivInfo     
  12. {     
  13.   sem_t    sem;     
  14.   int      lock_var;     
  15.   time_t   end_time;     
  16. }PrivInfo;     
  17.     
  18. static void info_init (PrivInfo* thiz);     
  19. static void *pthread_func_1 (void* thiz);     
  20. static void *pthread_func_2 (void* thiz);     
  21.     
  22. int main (int argc, char** argv)     
  23. {     
  24.   pthread_t pt_1 = 0;     
  25.   pthread_t pt_2 = 0;     
  26.   int ret = 0;     
  27.   PrivInfo* thiz = NULL;     
  28.     
  29.   thiz = (PrivInfo* )malloc (sizeof (PrivInfo));     
  30.   if (thiz == NULL)     
  31.   {     
  32.     printf ("[%s]:Failed to malloc PrivInfo./n");     
  33.     return -1;     
  34.   }     
  35.     
  36.   info_init (thiz);     
  37.        
  38.   ret = pthread_create (&pt_1, NULL, pthread_func_1, thiz);     
  39.   if (ret != 0)     
  40.   {     
  41.     perror ("pthread_1_create:");     
  42.   }     
  43.     
  44.   ret = pthread_create (&pt_1, NULL, pthread_func_2, thiz);     
  45.   if (ret != 0)     
  46.   {     
  47.     perror ("pthread_2_create:");     
  48.   }     
  49.     
  50.   pthread_join (pt_1, NULL);     
  51.   pthread_join (pt_2, NULL);     
  52.     
  53.   sem_destroy (&thiz->sem);     
  54.   free (thiz);     
  55.   thiz = NULL;     
  56.     
  57.   return 0;     
  58. }     
  59.     
  60. static void info_init (PrivInfo* thiz)     
  61. {     
  62.     
  63.    thiz->lock_var = 0;     
  64.    thiz->end_time = time(NULL) + 10;     
  65.     
  66.    sem_init (&thiz->sem, 0,  1);     
  67.     
  68.    return;     
  69. }     
  70.     
  71. static void *pthread_func_1 (void* th)     
  72. {   
  73.   return_if_fail(th);  
  74.     
  75.   int i = 0;     
  76.   PrivInfo* thiz = (PrivInfo*)th;  
  77.   while (time(NULL) < thiz->end_time)     
  78.   {     
  79.      sem_wait (&thiz->sem);     
  80.      printf ("pthread: pthread1 get lock./n");     
  81.      printf ("the lock_var = %d/n", thiz->lock_var);   
  82.      for (i = 0; i < 2; i ++)     
  83.      {     
  84.          thiz->lock_var ++;     
  85.          sleep (1);     
  86.      }     
  87.     
  88.      sem_post (&thiz->sem);     
  89.        
  90.      sleep (1);    
  91.   }     
  92.   
  93.   
  94.    return NULL;     
  95. }     
  96.     
  97. static void *pthread_func_2 (void* th)     
  98. {    
  99.    return_if_fail(th);  
  100.     
  101.    PrivInfo* thiz = (PrivInfo*)th;  
  102.    while (time (NULL) < thiz->end_time)     
  103.    {     
  104.       sem_wait (&thiz->sem);     
  105.       printf ("pthread2: pthread2 get lock!/n");     
  106.       printf ("the lock_var = %d/n", thiz->lock_var);     
  107.     
  108.       sem_post (&thiz->sem);     
  109.     
  110.     
  111.       sleep (3);     
  112.   
  113.    }     
  114.   
  115.   
  116.    return NULL;     
  117. }