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;
    }
    
  • 相关阅读:
    java NIO 总结
    NIO 服务器和客户端 demo
    nio channel demo
    使用docker制作zookeeper镜像
    java BIO模型demo
    IDEA中语句添加try....catch..语句块
    线程的几种创建方式
    海豚调度Dolphinscheduler源码分析(四)
    @PostConstruct注解
    zookeeper常用命令
  • 原文地址:https://www.cnblogs.com/wangdongfang/p/14540895.html
Copyright © 2011-2022 走看看