zoukankan      html  css  js  c++  java
  • 【线程】多线程同步互斥-互斥锁,生产者消费者问题

    互斥锁

      互斥锁用来保证同一时间内只有一个线程在执行某段代码(临界区)。多线程编程最容易出问题的地方,就是临界区的界定和访问控制。

      下面是一个生产者,消费者的简单例子。生产者、消费者公用一个缓冲区,这里假定缓冲区只能存放一条消息。

    生产者,消费者互斥

     1 //生产者,消费者问题
     2 //生产者、消费者公用一个缓冲区,这里假定缓冲区只能存放一条消息。
     3 
     4 
     5 #include <stdio.h>
     6 #include <stdlib.h>
     7 #include <pthread.h>
     8 #include <sys/time.h>
     9 
    10 static char buff[50];
    11 int have_msg=0;
    12 pthread_mutex_t mutex;
    13 int delay=1;
    14 
    15 void consumeItem(char *buff)
    16 {
    17     printf("consumer item
    ");
    18 }
    19 
    20 void produceItem(char *buff)
    21 {
    22     printf("produce item
    ");
    23 }
    24 
    25 void *consumer(void *param)//消费者进程回调函数
    26 {
    27     while (1)
    28     {
    29         pthread_mutex_lock(&mutex);
    30         if (have_msg>0)
    31         {
    32             have_msg--;
    33             consumeItem(buff);
    34         }
    35         pthread_mutex_unlock(&mutex);
    36         sleep(delay);
    37     }
    38     return NULL;
    39 }
    40 
    41 void *producer(void *param)//生产者进程回调函数
    42 {
    43     while (1)
    44     {
    45         pthread_mutex_lock(&mutex);
    46         if (have_msg==0)
    47         {
    48             have_msg++;
    49             produceItem(buff);
    50         }
    51         pthread_mutex_unlock(&mutex);
    52         sleep(delay);
    53     }
    54     return NULL;
    55 }
    56 
    57 //主函数
    58 int main()
    59 {
    60     pthread_t tid_c, tid_p;
    61     void *retval;
    62     
    63     pthread_mutex_init(&mutex, NULL);//默认属性初始化锁
    64     
    65     pthread_create(&tid_p, NULL, producer, NULL);
    66     pthread_create(&tid_c, NULL, consumer, NULL);
    67 
    68     pthread_join(tid_p, &retval);
    69     pthread_join(tid_c, &retval);
    70 
    71     return 0;
    72 }
    View Code

      

      输出一定是这样的:

    1 produce item
    2 consumer item
    3 produce item
    4 consumer item
    5 produce item
    6 consumer item
    7 produce item
    8 consumer item
    View Code

      

      互斥锁最简单的使用是这样的:

    pthread_mutex_t mutex;                   //定义锁
    pthread_mutex_init(&mutex, NULL);   //默认属性初始化锁
    pthread_mutex_lock(&mutex);           //申请锁
    ...
    pthread_mutex_unlock(&mutex);       //释放锁

      

    设置锁的属性

      函数pthread_mutexattr_setpshared和函数pthread_mutexattr_settype用来设置互斥锁属性。


      前者设置属性pshared,它有两个取值,PTHREAD_PROCESS_PRIVATEPTHREAD_PROCESS_SHARED

    1. 前者用来不同进程中的线程同步
    2. 后者用于同步本进程的不同线程。

      在上面的例子中,我们使用的是默认属性PTHREAD_PROCESS_ PRIVATE。

      后者用来设置互斥锁类型,可选的类型有PTHREAD_MUTEX_NORMAL、PTHREAD_MUTEX_ERRORCHECK、PTHREAD_MUTEX_RECURSIVE和PTHREAD _MUTEX_DEFAULT。

      它们分别定义了不同的上所、解锁机制,一般情况下,选用最后一个默认属性。

      用法如下:

    1 pthread_mutexattr_t mutexAttr;
    2 pthread_mutexattr_init(&mutexAttr);
    3 pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_PRIVATE);
    4 pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_DEFAULT);
    5 pthread_mutex_init(&mutex, &mutexAttr);

      pthread_mutex_lock阻塞线程直到pthread_mutex_unlock被调用。

      还有另外两个函数可以用:

    int pthread_mutex_trylock (pthread_mutex_t *__mutex)

      该函数立即返回,根据返回状态判断加锁是否成功。

    int pthread_mutex_timedlock (pthread_mutex_t *mutex, struct timespec *__restrict)

      该函数超时返回。

      互斥锁主要用来互斥访问临界区。用于线程的互斥。

  • 相关阅读:
    Eth-Trunk 技术
    MSTP技术
    STP生成树原理及不足
    表示数值的字符串(python)
    字符流中第一个不重复的字符(python)
    连续子数组的最大和(python)
    和为S的两个数字(python)
    数组中重复的数字(python)
    构建乘积数组(python)
    idea中查看类层级class hierarchy
  • 原文地址:https://www.cnblogs.com/lcw/p/3236470.html
Copyright © 2011-2022 走看看