linux多线程学习(六)——信号量实现同步


在上一篇文章中已经用信号量来实现线程间的互斥,达到了互斥锁的效果,今天这篇文章将讲述怎样用信号量去实现同步。

信号量的互斥同步都是通过PV原语来操作的,我们可以通过注册两个信号量,让它们在互斥的问题上互动,从而达到同步。通过下面实例就可以很容易理解:

 

[cpp]  view plain copy
  1. #include <stdlib.h>    
  2. #include <stdio.h>    
  3. #include <unistd.h>    
  4. #include <pthread.h>    
  5. #include <semaphore.h>    
  6. #include <errno.h>    
  7.     
  8. #define  return_if_fail(p)  if((p) == 0){printf ("[%s]:func error!/n", __func__);return;}    
  9.     
  10. typedef struct _PrivInfo    
  11. {    
  12.   sem_t s1;    
  13.   sem_t s2;    
  14.   time_t end_time;    
  15. }PrivInfo;    
  16.     
  17. static void info_init (PrivInfo* thiz);    
  18. static void info_destroy (PrivInfo* thiz);    
  19. static void* pthread_func_1 (PrivInfo* thiz);    
  20. static void* pthread_func_2 (PrivInfo* 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 priv./n");    
  33.     return -1;    
  34.   }    
  35.     
  36.   info_init (thiz);    
  37.     
  38.   ret = pthread_create (&pt_1, NULL, (void*)pthread_func_1, thiz);    
  39.   if (ret != 0)    
  40.   {    
  41.     perror ("pthread_1_create:");    
  42.   }    
  43.     
  44.   ret = pthread_create (&pt_2, NULL, (void*)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.   info_destroy (thiz);    
  54.       
  55.   return 0;    
  56. }    
  57.     
  58. static void info_init (PrivInfo* thiz)    
  59. {    
  60.   return_if_fail (thiz != NULL);    
  61.     
  62.   thiz->end_time = time(NULL) + 10;    
  63.       
  64.   sem_init (&thiz->s1, 0, 1);    
  65.   sem_init (&thiz->s2, 0, 0);    
  66.     
  67.   return;    
  68. }    
  69.     
  70. static void info_destroy (PrivInfo* thiz)    
  71. {    
  72.   return_if_fail (thiz != NULL);    
  73.     
  74.   sem_destroy (&thiz->s1);    
  75.   sem_destroy (&thiz->s2);    
  76.     
  77.   free (thiz);    
  78.   thiz = NULL;    
  79.     
  80.   return;    
  81. }    
  82.     
  83. static void* pthread_func_1 (PrivInfo* thiz)    
  84. {    
  85.   return_if_fail (thiz != NULL);    
  86.     
  87.   while (time(NULL) < thiz->end_time)    
  88.   {    
  89.     sem_wait (&thiz->s2);    
  90.     printf ("pthread1: pthread1 get the lock./n");    
  91.     
  92.     sem_post (&thiz->s1);    
  93.     printf ("pthread1: pthread1 unlock/n");    
  94.     
  95.     sleep (1);    
  96.   }    
  97.     
  98.   return;    
  99. }    
  100.     
  101. static void* pthread_func_2 (PrivInfo* thiz)    
  102. {    
  103.   return_if_fail (thiz != NULL);    
  104.     
  105.   while (time (NULL) < thiz->end_time)    
  106.   {    
  107.     sem_wait (&thiz->s1);    
  108.     printf ("pthread2: pthread2 get the unlock./n");    
  109.     
  110.     sem_post (&thiz->s2);    
  111.     printf ("pthread2: pthread2 unlock./n");    
  112.     
  113.     sleep (1);    
  114.   }    
  115.     
  116.   return;    
  117. }    

通过执行结果后,可以看出,会先执行线程二的函数,然后再执行线程一的函数。它们两就实现了同步。在上大学的时候,虽然对这些概念知道,可都没有实践过,所以有时候时间一久就会模糊甚至忘记,到了工作如果还保持这么一种状态,那就太可怕了。虽然现在外面的技术在不断的变化更新,可是不管怎么变,其核心技术还是依旧的,所以我们必须要打好自己的基础,再学习其他新的知识,那时候再学新的知识也会觉得比较简单的。闲话多说了两句,在下一篇文章中,我们将会实现一个经典的实例回顾这段时间对多线程的学习,那就是消费者和生产者。

 

~~END~~

你可能感兴趣的:(linux多线程学习(六)——信号量实现同步)