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)

      该函数超时返回。

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

  • 相关阅读:
    JZOJ 3034. 【NOIP2012模拟10.17】独立集
    JZOJ 3035. 【NOIP2012模拟10.17】铁轨
    JZOJ 1259. 牛棚安排
    数位DP JZOJ 3316. 非回文数字
    JZOJ 3046. 游戏
    JZOJ 3013. 填充棋盘
    debian 安装oracle提供的java8
    java 汉字转拼音 PinYin4j
    debian ssh设置root权限登陆 Permission denied, please try again
    java并发下订单生成策略
  • 原文地址:https://www.cnblogs.com/lcw/p/3236470.html
Copyright © 2011-2022 走看看