zoukankan      html  css  js  c++  java
  • 互斥锁不在同一个线程内引发的问题

    本实验创建了3个进程,为了更好的描述线程之间的并行执行, 让3个线程共用同一个执行函数。每个线程都有5次循环(可以看成5个小任务), 每次循环之间会随机等待1~10s的时间,意义在于模拟每个任务的到达时间是随机的,并没有任何特定的规律。使用互斥锁mutex完成互斥访问

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <pthread.h>
     4 
     5 #define THREAD_NUMBER 3         //线程数
     6 #define REPAT_NUMBER 5          //每个线程中的小任务数
     7 #define DELAY_TIME_LEVELS 10.0  //小任务之间的最大时间间隔
     8 pthread_mutex_t mutex;          //定义一格互斥锁的全局变量
     9 
    10 //线程函数例程
    11 void *func(void *arg)
    12 {
    13         int thrd_num=(int )arg;
    14         int delay_time=0;
    15         int count=0;
    16         int res;
    17         //互斥锁上锁
    18         res=pthread_mutex_lock(&mutex);
    19         if(res!=0){
    20                 printf("Thread %d lock failed.
    ",thrd_num);
    21                 pthread_exit(NULL);
    22         }   
    23         //下面这段代码才是共享区
    24         printf("thread %d is starting
    ", thrd_num);
    25         for(count=0; count<REPAT_NUMBER; count++){
    26                 delay_time=(int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX))+1;
    27                 sleep(delay_time);
    28                 printf("	thread %d:job %d delay %d
    ", thrd_num, count, delay_time);
    29         }   
    30         printf("thread %d finished
    ",thrd_num);
    31         //互斥锁的解锁留给了主线程
    32         pthread_mutex_unlock(&mutex);
    33         pthread_exit(NULL);     //线程退出
    34 }
    35 
    36 int main(int argc, char const *argv[])
    37 {
    38         pthread_t thread[THREAD_NUMBER];        //存放线程ID
    39         int no,res;
    40         void *thrd_ret;
    41         srand(time(NULL));
    42 
    43         for(no=0; no<THREAD_NUMBER; no++){
    44                 //创建多线程
    45                 res=pthread_create(&thread[no],NULL,(void *)func,(void *)no);
    46                 if(res!=0){
    47                         printf("create thread %d failed.
    ", no);
    48                         exit(res);
    49                 }
    50         }
    51 
    52         printf("create thread success
    waiting for thread to finish...
    ");
    53         for(no=0; no<THREAD_NUMBER; no++){
    54                 //等待线程结束
    55                 res=pthread_join(thread[no],&thrd_ret);
    56                 if(!res){
    57                         printf("thread %d finished
    ", no);
    58                 }else{
    59                         printf("thread %d join failed.
    ", no);
    60                 }
    61                 //互斥锁解锁
    62    //           pthread_mutex_unlock(&mutex);
    63         }
    64         return 0;
    65 }
    View Code

     这里要注意32行和62行的解锁,如果使用的是32行注释掉62行,则程序能正常运行

    但如果使用的是62行而注释掉32行的话,程序会在某个地方卡住,运行了13次,下面第二种情况只出现了2次。

    猜想:只要thread 2 结束了,在main函数里的for循环也就结束了。那main就return了,这样,剩下还没运行的子线程就被杀死不执行。

    不过,从执行成功的情况来看,以上猜想不成立……

  • 相关阅读:
    linux一切皆文件之tcp socket描述符(三)
    linux一切皆文件之Unix domain socket描述符(二)
    linux一切皆文件之文件描述符(一)
    k8s之使用secret获取私有仓库镜像
    https、ssl、tls协议学习
    k8s网络之calico学习
    泛型的原理、应用、约束、缓存
    C#中Unity对象的注册方式与生命周期解析
    监听EF执行的sql语句及状态
    递归一个List<T>,可自己根据需要改造为通用型。
  • 原文地址:https://www.cnblogs.com/fallenmoon/p/6761306.html
Copyright © 2011-2022 走看看