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;

    }

  • 相关阅读:
    Java高级之类结构的认识
    14.8.9 Clustered and Secondary Indexes
    14.8.4 Moving or Copying InnoDB Tables to Another Machine 移动或者拷贝 InnoDB 表到另外机器
    14.8.3 Physical Row Structure of InnoDB Tables InnoDB 表的物理行结构
    14.8.2 Role of the .frm File for InnoDB Tables InnoDB 表得到 .frm文件的作用
    14.8.1 Creating InnoDB Tables 创建InnoDB 表
    14.7.4 InnoDB File-Per-Table Tablespaces
    14.7.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量和大小
    14.7.1 Resizing the InnoDB System Tablespace InnoDB 系统表空间大小
    14.6.11 Configuring Optimizer Statistics for InnoDB 配置优化统计信息用于InnoDB
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/9216026.html
Copyright © 2011-2022 走看看