zoukankan      html  css  js  c++  java
  • linux线程--线程间同步机制

    linux线程--线程间同步机制

    linux实现线程间同步主要有如下三个手段:

    mutex(互斥变量)/cond(条件变量)/sem(信号量)

    mutex互斥变量

    互斥变量是实现线程同步的一个重要手段,通过对互斥变量加解锁机制,可以实现线程的同步。

    一个线程对一个互斥变量加锁,而其他任何一个线程想再次对互斥变量加锁时都会被阻塞,直到加锁线程释放互斥锁。

    互斥锁有一个很明显的特点就是哪个线程对互斥变量加锁,必须有哪个线程对互斥变量解锁

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <pthread.h>
    #include <unistd.h>
    #include <vector>
    #include <queue>
    #include "main.h"
    
    using namespace std;
    pthread_mutex_t mutex;
    queue<int>qe;
    
    void* threadFunc1(void* arg)
    {
        for (int index = 0; index<10; index++) {
            pthread_mutex_lock(&mutex);
            printf("this is func1
    ");
            qe.push(index);
            pthread_mutex_unlock(&mutex);
        }
        return nullptr;
    }
    
    void* threadFunc2(void* arg)
    {
        for (int index = 0; index<10; index++) {
            pthread_mutex_lock(&mutex);
            printf("this is func2
    ");
            printf("this is %d
    ", qe.front());
            qe.pop();
                pthread_mutex_unlock(&mutex);
        }
        return nullptr;
    }
    
    int main()
    {
        pthread_mutex_init(&mutex, NULL);
        pthread_t pid1, pid2, pid3,pid4;
        pthread_create(&pid1, NULL, threadFunc1, NULL);
        pthread_create(&pid2, NULL, threadFunc2, NULL);
    
        void* ret;
        pthread_join(pid1, &ret);
        pthread_join(pid2, &ret);
    
        pthread_mutex_destroy(&mutex); // 销毁线程锁
    
        return 0;
    }
    

    pthread_cond_t条件变量

    条件变量是实现线程同步的另一个重要手段,可以使用条件变量等待另一个线程的结束,条件变量一般痛互斥变量一起使用

    条件变量的一个重要表象就是一个线程等待另外的线程发送信号

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <pthread.h>
    #include <unistd.h>
    #include <vector>
    #include "main.h"
    
    using namespace std;
    pthread_mutex_t mutex;
    queue<int>qe;
    uint32_t sum = 0;
    
    void* threadFunc1(void* arg)
    {
        pthread_mutex_lock(&mutex);
        sum++
        pthread_mutex_unlock(&mutex);
        return nullptr;
    }
    
    void* threadFunc2(void* arg)
    {
        pthread_mutex_lock(&mutex);
        if (sum >= 100) {
            printf("sum is reach 100
    ");
            sum = 0;
        } else if (sum < 100) {
            sleep(1);
        }
        pthread_mutex_unlock(&mutex);
        return nullptr;
    }
    
    int main()
    {
        pthread_mutex_init(&mutex, NULL);
        pthread_t pid1, pid2, pid3,pid4;
        pthread_create_t(pid1, NULL, threadFunc1, NULL);
        pthread_create_t(pid2, NULL, threadFunc2, NULL);
    
        void* ret;
        pthread_join(pid1, &ret);
        pthread_join(pid2, &ret);
    
        pthread_mutex_destroy(&mutex); // 销毁线程锁
    
        return 0;
    }
    

    但是这样会引起如下问题:

    1、大多数情况下,sum的数值不会到达100,就是函数大部分时间会进入else分支,sleep(1),这样会引起pid4的执行效率变慢,且sleep(1)之后,sum的数值可能已经非常大了。

    2、sleep的数值取值非常麻烦,取得小会频繁的sleep,浪费CPU资源;取的大会无法把控

    这个时候条件变量就起作用了,我们可以设置一个条件变量,当条件满足时,向等待的线程发送信号。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <pthread.h>
    #include <unistd.h>
    #include <queue>
    #include <vector>
    #include "main.h"
    
    using namespace std;
    pthread_mutex_t mutex;
    queue<int>qe;
    uint32_t sum = 0;
    pthread_cond_t cond_sum_ready = PTHREAD_COND_INITIALIZER;
    
    static void* threadFunc1(void* arg)
    {
        pthread_mutex_lock(&mutex);
        sum++;
        printf("sum = %d
    ", sum);
        if (sum >= 100) {
            pthread_cond_signal(&cond_sum_ready);
        }
        pthread_mutex_unlock(&mutex);
        return nullptr;
    }
    
    static void* threadFunc2(void* arg)
    {
        pthread_mutex_lock(&mutex);
        while(sum < 100) {
            printf("pthread4 unlock mutex
    ");
            pthread_cond_wait(&cond_sum_ready, &mutex);
        }
        printf("sum is reach 100");
        sum = 0;
        pthread_mutex_unlock(&mutex);
        return nullptr;
    }
    
    int main()
    {
        pthread_mutex_init(&mutex, NULL);
        pthread_t pid1, pid2, pid3, pid4;
        pthread_create(&pid1, NULL, threadFunc1, NULL);
        pthread_create(&pid2, NULL, threadFunc1, NULL);
        pthread_create(&pid3, NULL, threadFunc1, NULL);
        pthread_create(&pid4, NULL, threadFunc2, NULL);
    
        void* ret;
        pthread_join(pid1, &ret);
        pthread_join(pid2, &ret);
        pthread_join(pid3, &ret);
        pthread_join(pid4, &ret);
        pthread_mutex_destroy(&mutex); // 销毁线程锁
    
        return 0;
    }
    
  • 相关阅读:
    (原)Lazarus 异构平台下多层架构思路、DataSet转换核心代码
    (学)新版动态表单研发,阶段成果3
    (学) 如何将 Oracle 序列 重置 清零 How to reset an Oracle sequence
    (学)XtraReport WebService Print 报错
    (原)三星 i6410 刷机 短信 无法 保存 解决 办法
    (原) Devexpress 汉化包 制作工具、测试程序
    linux下网络配置
    apache自带ab.exe小工具使用小结
    Yii::app()用法小结
    PDO使用小结
  • 原文地址:https://www.cnblogs.com/wangdongfang/p/14540895.html
Copyright © 2011-2022 走看看