线程同步与互斥---互斥量,条件变量

互斥量的引入:

很多变量在线程间共享,通过数据的共享完成线程之间的交互
解决多个线程并发的操作共享变量带来的问题

互斥量实现的要求:
1 当代码进入临界区,不允许其他线程进入该临界区
2 若线程不在临界区执行,该线程不能阻止其他线程进入临界区
3 多线程同时要求执行临界区代码,且临界区没线程执行,则允许一个线程进入临界区

互斥量相关函数
初始化:
静态分配:pthread_mutex_t mutex
动态分配:pthread_mutex_init
互斥量加锁:
pthread_mutex_lock
互斥量解锁
pthread_mutex_unlock
互斥量销毁
pthread_mutex_destroy

互斥量加锁注意:

1 互斥量处于未锁状态,函数将互斥量锁定,返回成功。
2 发起函数调用时,其他线程已经锁定,或其他线程同时申请互斥量,
但没有竞争到互斥量,那么pthread_lock调用会陷入阻塞,等待互斥量解锁

互斥量销毁注意:

1 使用静态分配初始化的互斥量不需要销毁
2 不要销毁一个已经加锁的互斥量
3 已销毁的互斥量确保后面不会线程再尝试加锁

改进版售票系统

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<sched.h>

int ticket=100;
pthread_mutex_t mutex; //定义互斥量

void* route(void *arg)
{
    char *id=(char*)arg;
    while(1)
    {
        pthread_mutex_lock(&mutex);//互斥量加锁
        if(ticket>0)
        {
            usleep(10000);
            printf("%s sells ticket: %d\n",id,ticket);
            ticket--;
            pthread_mutex_unlock(&mutex); //互斥量解锁
        }
        else
        {
            pthread_mutex_unlock(&mutex);//互斥量解锁,退出
            break;
        }
    }
}

int main()
{
    pthread_t t1, t2, t3, t4;

    pthread_mutex_init(&mutex,NULL);

    pthread_create(&t1,NULL,route,"pthread1");//创建线程 1,2,3,4,
    pthread_create(&t2,NULL,route,"pthread2");
    pthread_create(&t3,NULL,route,"pthread3");
    pthread_create(&t4,NULL,route,"pthread4");

    pthread_join(t1,NULL);  //线程1,2,3,4,等待
    pthread_join(t2,NULL);
    pthread_join(t3,NULL);
    pthread_join(t4,NULL);

    pthread_mutex_destroy(&mutex); //销毁互斥量
}

这里写图片描述

条件变量的引入

描述资源就绪与否的状态,为实现同步(协调多线程之间的饥饿问题)而引入。

函数接口
pthread_cond_init 条件变量初始

pthread_cond_destroy 条件变量销毁

pthread_cond_wait 等待条件满足

   即:解锁互斥量并等待条件变量触发   

pthread_cond_signal 唤醒等待

  即:唤醒条件变量等待的上一个线程

pthread_cond_broadcast 唤醒等待

 即:唤醒条件变量等待的上一个线程
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>

pthread_cond_t cond;  //声明条件变量
pthread_mutex_t mutex; //声明互斥量

void* r1(void* arg)
{

    while(1)
    {
        printf("传球!\n");
        pthread_cond_signal(&cond);  //唤醒等待
        usleep(789123);
    }
    return NULL;
}

void* r2(void* arg)
{
    while(1)
    {
        pthread_cond_wait(&cond,&mutex); //条件变量等待
        printf("投篮!\n");
        usleep(123456);
    }
    return NULL;
}


int  main(void)
{
    pthread_t t1, t2;

    pthread_cond_init(&cond,NULL); //初始化条件变量
    pthread_mutex_init(&mutex,NULL); //初始化互斥量

    pthread_create(&t1,NULL,r1,NULL);//创建线程1,2
    pthread_create(&t2,NULL,r2,NULL);

    pthread_join(t1,NULL);//线程1,2等待
    pthread_join(t2,NULL);

    pthread_mutex_destroy(&mutex);//销毁互斥量
    pthread_cond_destroy(&cond);//销毁条件变量
    return 0;
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/yu876876/article/details/81475252
今日推荐