zoukankan      html  css  js  c++  java
  • 25多线程之互斥锁

    例子:利用两个子进程从50进行降序输出

    int g_num=50;

    //偶数

    void *threadEven(void *lParam)

    {

          while(g_num>0)

          {

               if(!(g_num&1))

               {

                     printf("even:%d ",g_num);

               }

               g_num--;

               usleep(1);

          }

          return NULL;

    }

    //奇数

    void *threadOdd(void *lParam)

    {

          while(g_num>0)

          {

               if(g_num&1)     

               {

                     printf("odd:%d ",g_num);

               }

               g_num--;

               usleep(1);

          }

          return NULL;

    }

    void testMutex()

    {

          pthread_t thread1,thread2;

          int nRet1=pthread_create(&thread1,NULL,threadOdd,NULL);

          int nRet2=pthread_create(&thread2,NULL,threadEven,NULL);

          printf("thread1 id:%d thread2 id:%d ",(int)thread1,(int)thread2);

         

          if(nRet1||nRet2)

          {

               fprintf(stderr,"fail to create thread!");

               return ;

          }

         

          pthread_join(thread1,NULL);

          pthread_join(thread2,NULL);

    }

    int main(int argc,char**argv)

    {

          testMutex();

          return 0;

    }

    上面的代码表示,创建两个子进程,子进程threadOdd输出奇数,子进程threadEven输出偶数。并且奇偶数是交替输出。即从50降序输出。

    如果实现奇偶数分开输出,如:先把50内的奇数或偶数输出。此时就要加锁。

    线程互斥

    多线程共享进程资源,访问共享资源时候,需要进行互斥操作确保数据的有效性

    什么是锁操作:

    比如:两人进屋子拿东西,A先进去反锁屋子,那么B就进不去。只有等A开锁出来后,才轮到B进去。

    锁类型设置/获取

    int pthread_mutexattr_settype(pthread_mutexattr_t*  attr, int type);

    int pthread_mutexattr_gettype(pthread_mutexattr_t*  attr, int *type);

    type参数:

    mutex 锁类型  PTHREAD_MUTEX_XXX

    NORMAL:           普通锁,不提供死锁检测,可能出现死锁

    ERRORCHECK:    检错锁,同一线程对已锁的互斥锁加锁会返回错误

    RECURSIVE:       嵌套锁,允许同一线程多次锁定而不产生死锁,多次释放才能被别的线程锁定

    DEFAULT:           默认为普通锁,排队获取锁

    创建互斥锁

    pthread_mutex_init(pthread_mutex_t  *mutex, pthread_mutexattr_t  *attr)

    注意:

    attr == NULL 初始化的线程锁 mutex

    等价于 mutex = PTHREAD_MUTEX_INITIALIZER

    互斥锁加锁

    pthread_mutex_lock(pthread_mutex_t  *mutex)

    对互斥锁加锁

    同一线程内对已经加锁的互斥锁,进行再次加锁,会造成死锁

    互斥锁解锁

    pthread_mutex_unlock(pthread_mutex_t  *mutex)

    释放互斥锁

    对未锁定的互斥锁,进行释放操作,会产生不确定的行为

    尝试解除有其他线程创建的互斥锁,会产生不确定的行为

    pthread_mutex_trylock(pthread_mutex_t  *mutex)

    试图锁住互斥体,不阻塞

    1: 互斥体未上锁,锁定并返回成功

    2: 互斥体已经上锁,不阻塞直接返回失败

    3: 锁类型为嵌套锁 RECURSIVE,  已上锁,则锁计数器自加

    问题:若使用man无法查询文档?pthread_mutex_*  函数族 man 无显示解决办法

    解决方式:$ sudo apt-get install manpages-posix-dev

    例子:利用互斥锁,两个子进程分开输出50的奇偶数

    pthread_mutex_t  mutex;

    int g_num=50;

    void *threadEven(void *lParam)

    {

          //加锁

          pthread_mutex_lock(&mutex);

          while(g_num>0)

          {

               if(!(g_num&1))

               {

                     printf("even:%d ",g_num);

               }

               g_num--;

               usleep(1);

              

          }

          g_num=50;

          //解锁

          pthread_mutex_unlock(&mutex);

          return NULL;

    }

    void *threadOdd(void *lParam)

    {

          //加锁

          pthread_mutex_lock(&mutex);

          while(g_num>0)

          {

               if(g_num&1)

               {

                     printf("odd:%d ",g_num);

               }

               g_num--;

               usleep(1);

              

          }

          g_num=50;

          //解锁

          pthread_mutex_unlock(&mutex);

          return NULL;

    }

    void testMutex()

    {

          pthread_t thread1,thread2;

          //初始化互斥锁

          pthread_mutex_init(&mutex,NULL);

         

    int nRet1=pthread_create(&thread1,NULL,threadOdd,NULL);

          int nRet2=pthread_create(&thread2,NULL,threadEven,NULL);

          printf("thread1 id:%d thread2 id:%d ",(int)thread1,(int)thread2);

         

          if(nRet1||nRet2)

          {

               fprintf(stderr,"fail to create thread!");

               return ;

          }

         

          pthread_join(thread1,NULL);

          pthread_join(thread2,NULL);

    }

    int main(int argc,char**argv)

    {

          testMutex();

          return 0;

    }

    以上是实现,奇偶数分开输出。

    ERRORCHECK和RECURSIVE属性:

    例子:锁上加锁,ERRORCHECK错误返回

    #include<stdio.h>

    #include<pthread.h>

    #include<stdlib.h>

    #include<unistd.h>

    #include<string.h>

    pthread_mutex_t  mutex;

    int g_num=50;

    //验证死锁

    void *thread()

    {

          int nRet=pthread_mutex_lock(&mutex);

          if(nRet)

          {

               printf("repeat lock! ");

               return NULL;

          }

          printf("test:%d ",g_num);

          pthread_mutex_unlock(&mutex);

          return NULL;

    }

    void *threadEven(void *lParam)

    {

          int nRet=pthread_mutex_lock(&mutex);

          if(nRet)

          {

               printf("repeat lock! ");

               return NULL;

          }

          while(g_num>0)

          {

               if(!(g_num&1))

               {

                     printf("even:%d ",g_num);

               }

               g_num--;

               usleep(1);

              

          }

          g_num=50;

          thread();

          pthread_mutex_unlock(&mutex);

          return NULL;

    }

    void *threadOdd(void *lParam)

    {

          int nRet=pthread_mutex_lock(&mutex);

          if(nRet)

          {

               printf("repeat lock! ");

               return NULL;

          }

          while(g_num>0)

          {

               if(g_num&1)

               {

                     printf("odd:%d ",g_num);

               }

               g_num--;

               usleep(1);

              

          }

          g_num=50;

          thread();

          pthread_mutex_unlock(&mutex);

          return NULL;

    }

    void testMutex()

    {

          pthread_t thread1,thread2;

          pthread_mutexattr_t  attr;   

          //设置锁的属性

    //pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);

          pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK);

          //默认排队锁

          //pthread_mutex_init(&mutex,NULL);

          pthread_mutex_init(&mutex,&attr);

         

          int nRet1=pthread_create(&thread1,NULL,threadOdd,NULL);

          int nRet2=pthread_create(&thread2,NULL,threadEven,NULL);

          printf("thread1 id:%d thread2 id:%d ",(int)thread1,(int)thread2);

         

          if(nRet1||nRet2)

          {

               fprintf(stderr,"fail to create thread!");

               return ;

          }

         

          pthread_join(thread1,NULL);

          pthread_join(thread2,NULL);

    }

    int main(int argc,char**argv)

    {

          testMutex();

          return 0;

    }

  • 相关阅读:
    移动端WEB开发真机测试
    前端自学路线之js篇
    学习提高你CSS技术的法则
    day-5元组专区
    day5-列表专区
    day4-字符串专区
    day2-day3基本数据类型专区
    day1-习题
    day1-python条件语句和基本数据类型
    day1-python初识以及变量
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/9216026.html
Copyright © 2011-2022 走看看