• 【C语言_线程pthread_互斥锁mutex_条件触发cond 之解析与示例 (开源)】.md updata:23/11/03


    线程 pthread

    线程 vs 进程

    线程:直接用主程序的内存地址,所以如果在线程里改主程序变量,就是直接改;
    线程vs进程:
    a.比进程快大概30倍,不需要复制完全一样的内存来创建运行,直接使用主程序的内存;
    b.没有进程那么健壮,子线程蹦了,就都崩了;
    而对进程而言,子进程崩了,父进程不受影响继续执行;

    线程退出 等待 消息传递
    join:等待,传参void*; exit:退出,对参数赋值void**;
    #include <stdio.h>
    #include <pthread.h>
    #include <string.h>
    
    //创建线程
    //int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
    // 返回:若成功返回0,否则返回错误编号
    
    //子线程执行函数func1里的pthread_exit负责将void* 传递给主线程的pthread_joi的void **参数;
    //int pthread_exit(void *rval_ptr);
    
    // int pthread_join(pthread_t thread, void **rval_ptr);
    // 返回:若成功返回0,否则返回错误编号
    
    void *func1(void * arg)
    {
        static char data[] = "I am ok! thanks!";
        printf("t1 id:%d\n",(int)pthread_self());
        printf("t1 arg data:%s\n",(char* )arg);
        pthread_exit((void* )data);
    }
    
    int main()
    {
        pthread_t t1;
        char arg[] = "Are you ok?";
        char data1[1024];
        memset(data1,'\0',sizeof(data1));
    
        printf("main id:%d\n",(int)pthread_self());
        int creatN = pthread_create(&t1,NULL,func1, (void*)arg); 
        //创建其他线程,也是类似操作: 定义好执行函数func2,和传入的形参arg2即可;
        //pthread_create(&t2,NULL,func2, (void*)arg2); 
    
        void* ret;
        pthread_join(t1,&ret);
        strcpy(data1, (char*)ret);
        printf("t1 return data:%s\n",data1);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    互斥锁 mutex

    互斥锁:我上锁,你就不能用了,除非我解锁了,你才能用;
    配合线程使用;

    互斥锁mutex+条件cond_等待wait、触发signal 控制线程执行

    //例:

    #include <stdio.h>
    #include <pthread.h>
    #include <string.h>
    #include <unistd.h>
    
    /*-----------------------------------------------------*/
    // 创建互斥锁变量 
    //pthread_mutex_t 锁名
    // 初始化及销毁互斥锁
    // int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
    // int pthread_mutex_destroy(pthread_mutex_t mutex);
    // 返回:若成功返回0,否则返回错误编号
    
    //上锁 例:pthread_mutex_lock(&mutex);
    //解锁 例:pthread_mutex_unlock(&mutex);
    
    /*-----------------------------------------------------*/
    
    // 创建条件变量 
    //pthread_cond_t 条件名
    // 初始化及销毁条件变量
    // int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); //消息只给一个线程
    // int pthread_cond_destroy(pthread_cond_t *cond);  //广播给所有线程
    // 返回:若成功返回0,否则返回错误编号
    
    // 等待
    // int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
    // int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);
    // 返回:若成功返回0,否则返回错误编号
    
    //触发
    // int pthread_cond_signal(pthread_cond_t *cond);
    // int pthread_cond_broadcast(pthread_cond_t *cond);
    // 返回:若成功返回0,否则返回错误编号
    
    /*-----------------------------------------------------*/
    
    int numNB = 0;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    
    void *func1(void * arg)
    {
        printf("t1 id:%ld\n",(unsigned long)pthread_self());
        printf("t1 get main data:%s\n",(char* )arg);
        
        while(1){
            pthread_cond_wait(&cond,&mutex);
            printf("--------------------\n");
            printf("t1:%d\n",numNB++);
            printf("--------------------\n");
            sleep(1);
            numNB = 0;
        }
    
    }
    
    void *func2(void * arg)
    {
        printf("t2 id:%ld\n",(unsigned long)pthread_self());
        printf("t2 get main data:%s\n",(char* )arg);
        while(1){
            pthread_mutex_lock(&mutex);                
            printf("t2:%d\n",numNB++);
            pthread_mutex_unlock(&mutex);
            
            if(numNB == 3){
               pthread_cond_signal(&cond); 
            }     
            sleep(1);   
        } 
    }
    
    int main()
    {
        pthread_mutex_init(&mutex,NULL);
        pthread_cond_init(&cond,NULL);
        pthread_t t1,t2;
        void* ret;
        char arg[] = "Are you ok?";
        char data1[1024];
        memset(data1,'\0',sizeof(data1));
        
        int creatN1 = pthread_create(&t1,NULL,func1, (void*)arg);
        int creatN2 = pthread_create(&t2,NULL,func2, (void*)arg);
        
        printf("main id:%ld\n",(unsigned long)pthread_self());
    
        pthread_join(t1,&ret);
        pthread_join(t2,&ret);
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    补充: 宏-静态初始化 互斥锁/条件
    //在main函数里,不用宏,pthread_mutex_init() 正常初始化锁/条件的,即为动态初始化
    //例:
    pthread_mutex_t mutex;
    int main()
    {
        pthread_mutex_init(&mutex,NULL);
        return 0;
    }
    
    //在定义互斥锁/条件变量时,使用默认宏直接完成初始化,即为静态初始化
    //例:
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    npm设置淘宝镜像地址
    Flowable主要API介绍
    软件项目管理 6.10.成本预算
    java毕业设计开题报告论文基于JavaWeb酒店管理系统开发与设计
    C语言:数组名和数组地址
    【题解】二分答案+贪心-2
    代码随想录算法训练营第三十三天丨 贪心算法part04
    暑假算法训练day2
    FOC系列(二)----继续学习DRV8301芯片
    qt pro如何增加自定义值为的字符串的宏
  • 原文地址:https://blog.csdn.net/Wdf_123654/article/details/134195729