linux多线程学习(四)——互斥锁线程控制


在前面的文章中提及到,一个进程中的多个线程是共享同一段资源的,由于线程对资源的竞争引出了锁。其中mutex是一种简单的加锁方法,这个互斥锁只有两种状态,那就是上锁和解锁,可以把互斥锁看作是某种意义上的全局变量。在某一时刻,只能有一个线程取得这个互斥上的锁,拥有上锁状态的线程可以对共享资源进行操作,而其他线程在该线程未解锁之前,够会被挂起,直到上锁的线程解开锁。可以这么说,互斥锁使得共享资源按序的在各个线程上操作。

互斥锁的操作主要包括互斥锁初始化、上锁、判断上锁、解锁、摧毁互斥锁。其中互斥锁可以分为快速互斥锁、递归互斥锁这检错互斥锁。这三种锁的区别主要在于其他未占有互斥锁的线程在希望得到互斥锁时是否需要等待挂起。快速锁是指调用线程会阻塞直到线程锁得到解锁为止。递归锁能够成功地返回并且增加调用线程在互斥上的加锁次数,比如一个链表在进行插入的操作时,可以进行查找的操作。检错锁则为快速互斥锁的非阻塞版本,它会立即返回并返回一个错误的信息。

1、函数简义。

(1)pthread_mutex_init

头文件:                  <pthread.h>

函数原型:               int pthread_mutex_init (pthread_mutex_t* mutex,

                                                                         const pthread_mutexattr_t* mutexattr);

函数传入值:            mutex:互斥锁。

                              mutexattr:PTHREAD_MUTEX_INITIALIZER:创建快速互斥锁。 

                                               PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP:创建递归互斥锁。

                                               PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP:创建检错互斥锁。

函数返回值:            成功:0

                              出错:-1 

(2)上锁函数:

int pthread_mutex_lock(pthread_mutex_t* mutex);

int pthread_mutex_trylock (pthread_mutex_t* mutex);

int pthread_mutex_unlock (pthread_mutex_t* mutex);

int pthread_mutex_destroy (pthread_mutex_t* mutex);

函数传入值:            mutex:互斥锁。

函数返回值:            同上。

2、互斥锁实现。

[cpp]  view plain copy
  1. include <stdio.h>    
  2. #include <stdlib.h>    
  3. #include <pthread.h>    
  4. #include <errno.h>    
  5. #include <unistd.h>    
  6.     
  7. #define  return_if_fail(p)  /  
  8.     if((p) == 0){printf("[%s]:func error!/n",__func__);return;}    
  9.      
  10. typedef struct _PrivInfo    
  11. {    
  12.    pthread_mutex_t mutex;    
  13.    int lock_var;    
  14.    time_t end_time;    
  15. }PrivInfo;    
  16.     
  17. static void info_init (PrivInfo* thiz);    
  18. static void* pthread_func_1 (PrivInfo* thiz);    
  19. static void* pthread_func_2 (PrivInfo* thiz);    
  20.     
  21. int main (int argc, char** argv)    
  22. {    
  23.    pthread_t pt_1 = 0;    
  24.    pthread_t pt_2 = 0;    
  25.    int ret = 0;    
  26.    PrivInfo* thiz = NULL;    
  27.     
  28.    thiz = (PrivInfo*)malloc (sizeof (PrivInfo));    
  29.    if (thiz == NULL)    
  30.    {    
  31.       return -1;    
  32.    }    
  33.     
  34.    info_init(thiz);    
  35.     
  36.    ret = pthread_create (&pt_1, NULL, (void*)pthread_func_1, thiz);    
  37.    if (ret != 0)    
  38.    {    
  39.      perror ("pthread_1_create:");    
  40.    }    
  41.        
  42.    ret = pthread_create (&pt_2, NULL, (void*)pthread_func_2, thiz);    
  43.    {    
  44.      perror ("pthread_2_create:");    
  45.    }    
  46.     
  47.    pthread_join (pt_1, NULL);    
  48.    pthread_join (pt_2, NULL);    
  49.     
  50.    pthread_mutex_destroy (&thiz->mutex);    
  51.        
  52.    free (thiz);    
  53.    thiz = NULL;    
  54.     
  55.    return 0;    
  56. }    
  57.     
  58. static void info_init (PrivInfo* thiz)    
  59. {    
  60.    return_if_fail (thiz != NULL);    
  61.     
  62.    thiz->lock_var = 0;    
  63.    thiz->end_time = time (NULL) + 10;    
  64.     
  65.    pthread_mutex_init (&thiz->mutex, NULL);    
  66.     
  67.    return;    
  68. }    
  69.     
  70. static void* pthread_func_1 (PrivInfo* thiz)    
  71. {    
  72.    return_if_fail (thiz != NULL);    
  73.     
  74.    int i = 0;    
  75.    int ret = 0;    
  76.     
  77.    while (time (NULL) < thiz->end_time)    
  78.    {    
  79.      ret  = pthread_mutex_lock (&thiz->mutex);    
  80.      if (ret != 0)    
  81.      {    
  82.          perror ("[%s]pthread_mutex_lock");    
  83.      }    
  84.      else    
  85.      {    
  86.        printf ("pthread1:pthread1 lock the variable!/n");    
  87.      }    
  88.     
  89.      for (i = 0; i < 2; i++)    
  90.      {    
  91.         sleep (1);    
  92.         thiz->lock_var ++;    
  93.      }    
  94.     
  95.      ret = pthread_mutex_unlock (&thiz->mutex);    
  96.      if (ret != 0)    
  97.      {    
  98.         perror ("[%s]pthread_mutex_unlock");    
  99.      }    
  100.      else    
  101.      {    
  102.         printf ("pthread1: pthread1 unlock the variable./n");    
  103.      }         
  104.    }    
  105.     
  106.    return;    
  107. }    
  108.     
  109. static void* pthread_func_2 (PrivInfo* thiz)    
  110. {    
  111.    return_if_fail (thiz != NULL);    
  112.     
  113.    int ret = 0;    
  114.        
  115.    while (time (NULL) < thiz->end_time)    
  116.    {    
  117.       ret = pthread_mutex_trylock (&thiz->mutex);    
  118.       if (ret == EBUSY)    
  119.       {    
  120.          printf ("pthread2:the variable is locked by thread1./n");    
  121.       }    
  122.       else    
  123.       {    
  124.          if (ret != 0)    
  125.          {    
  126.              perror ("[%s]pthread2_mutex_trylock");     
  127.          }    
  128.          else    
  129.          {    
  130.             printf ("pthread2: pthread2 lock the variable./n");    
  131.          }             
  132.           
  133.     
  134.          ret = pthread_mutex_unlock (&thiz->mutex);    
  135.          if (ret != 0)    
  136.          {    
  137.            perror ("[%s]pthread_mutex_lock");    
  138.          }    
  139.     
  140.          sleep (3);    
  141.       }    
  142.     }    
  143. }    

在上例的中,是对变量lock_var的读写进行加锁,线程一是对其进行写,在写的时候,线程二不能对其进行读。直到线程一解锁,线程二得到互斥锁,才能进行读。同样,在线程二进行读的时候,线程一不能进行写。

今天讲述到这里,下一篇文章将讲述怎样通过信号量来达到互斥锁的效果。

你可能感兴趣的:(linux多线程学习(四)——互斥锁线程控制)