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;
}
原文地址:https://www.cnblogs.com/wangdongfang/p/14540895.html