ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

109_多线程_另一种同步条件变量+互斥锁【这里可以完成同步,但是注意:线程的执行顺序是同时进行的,所以对其中个别操作添加延时,以让部分步骤充分响应】【条件变量的broadcast、wait】

2021-09-11 18:34:52  阅读:193  来源: 互联网

标签:同步 变量 解锁 阻塞 线程 pthread mutex 多线程 上锁


动图–一个在打印里去掉了延时:

在这里插入图片描述
在这里插入图片描述

解析–提前看一下

两个线程的锁、解锁等操作,是同时进行的

进入线程, 1、 2开始抢资源
 1、
 1 抢到, 进入资源,那 2 就会阻塞住
然后打印"hello", 接着 1 线程开始解锁, /2 线程同步的会进入资源,上锁开始执行操作 
2 线程会迅速的进入资源,并且上锁 ,为了防止 2 线程会立刻打印"world"
我们为 2 线程 添加一个【条件变量】的阻塞,让它停在(阻塞)在执行【my_print】的外面


 2、
2 线程进入资源后, 会遇到 【条件变量】,它打开锁, 但是会阻塞在那里
此时 1线程,会执行【条件变量】broadcast函数, 对 2 线程中 的条件阻塞,发送唤醒指令
/*✳✳✳✳✳同时因为【条件变量】broadcast函数具有对【条件变量】解除阻塞 ‘+’ 【mutex】上锁的能力✳✳✳✳✳*/
所以 2 线程中的【条件变量】阻塞 函数, 会在接触阻塞的同时, 对【mutex】上锁
然后 2 线程放开阻塞, 进入 执行"world", 
执行完"world",  2 线程会立刻 解锁 === 1 线程立刻进入资源且上锁

1、
1 线程开始立刻执行,然后解锁,
那么此时, 上锁的 【条件变量】阻塞 函数就会防止 ,执行完 1 执行完, 立马执行 2 线程
只有在 1 线程执行到  发送解除阻塞、唤醒函数的时候, 2 线程才会进去执行

代码–两个线程中都必须添加延时:

#if 1 // ---------------- 2个线程 ------1个条件变量 -----//

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


pthread_mutex_t mutex;//= PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond;//条件变量

void my_print(char *str)
{
    //printf("%s\n", str);
    while (*str != '\0')
    {
        
        putchar(*str);
        fflush(stdout);

        str++;
        //sleep(1);//--可以不去

    }
    
    printf("\n");
}


void *callback_1(void *arg)
{
	//lock 尝试加锁,如果加锁不成功,线程阻塞,阻塞到持有该互斥量的其他线程【解锁】为止!!!
	//unlock 主动解锁函数,同时将阻塞在该锁上的所有线程全部唤醒,至于哪个线程先被唤醒,取决于优先级、调度。
	//默认:先阻塞、先唤醒。



    int i = 0;
    for(; i < 3; i++)
    {

        
        //加锁: --操作, 阻塞线程
        //上锁-可理解为将mutex–(或 -1),操作后mutex 的值为 0
        pthread_mutex_lock(&mutex); //1.1

        pthread_cond_wait(&cond, &mutex); //2.2//阻塞该任务,且打开锁,解除任务1的阻塞
        my_print("world"); //3.1
        //sleep(1);

        //解锁: ++操作, 换醒阻塞在锁上的线程
        //解锁-可理解为将mutex ++(或 +1),操作后mutex 的值为 1。
        pthread_mutex_unlock(&mutex);

        sleep(1);//延时一下,给线程 1 进入资源时间
    }
}

void *callback(void *arg)
{

    int i = 0;
    for(; i < 3; i++)
    {
        pthread_mutex_lock(&mutex); //1.

        my_print("hello");
        pthread_mutex_unlock(&mutex); //2.
        sleep(1);//用来缓冲上锁、解锁时间

        pthread_cond_broadcast(&cond); //3.解除所有在条件变量cond上的阻塞,同时上锁
        sleep(1);//用来缓冲上锁、解锁时间
    }
}

//两个线程的锁、解锁等操作,是同时进行的

//进入线程, 1、 2开始抢资源
// 1、
// 1 抢到, 进入资源,那 2 就会阻塞住
//然后打印"hello", 接着 1 线程开始解锁, /2 线程同步的会进入资源,上锁开始执行操作 
//2 线程会迅速的进入资源,并且上锁 ,为了防止 2 线程会立刻打印"world"
//我们为 2 线程 添加一个【条件变量】的阻塞,让它停在(阻塞)在执行【my_print】的外面


// 2、
//2 线程进入资源后, 会遇到 【条件变量】,它打开锁, 但是会阻塞在那里
//此时 1线程,会执行【条件变量】broadcast函数, 对 2 线程中 的条件阻塞,发送唤醒指令
/*✳✳✳✳✳同时因为【条件变量】broadcast函数具有对【条件变量】解除阻塞 ‘+’ 【mutex】上锁的能力✳✳✳✳✳*/
//所以 2 线程中的【条件变量】阻塞 函数, 会在接触阻塞的同时, 对【mutex】上锁
//然后 2 线程放开阻塞, 进入 执行"world", 
//执行完"world",  2 线程会立刻 解锁 === 1 线程立刻进入资源且上锁

//1、
//1 线程开始立刻执行,然后解锁,
//那么此时, 上锁的 【条件变量】阻塞 函数就会防止 ,执行完 1 执行完, 立马执行 2 线程
//只有在 1 线程执行到  发送解除阻塞、唤醒函数的时候, 2 线程才会进去执行



int main()
{

    pthread_cond_init(&cond, NULL);        


   int ret = pthread_mutex_init(&mutex, NULL);//申请动态锁。局部变量应采用动态初始化,正常返回【 0 】
   if(ret != 0)
    {
		fprintf(stderr,"mute init error:%d\n", ret);
		exit(1);
	}
    pthread_t pth, pth1;

    pthread_create(&pth,NULL, callback, NULL);//线程的创建
    pthread_create(&pth1,NULL, callback_1, NULL);

    pthread_join(pth, NULL);//线程等待回收(带阻塞)
    pthread_join(pth1, NULL);

    pthread_mutex_destroy(&mutex);//销毁互斥锁

    pthread_cond_destroy(&cond);

    return 0;
}

#endif

标签:同步,变量,解锁,阻塞,线程,pthread,mutex,多线程,上锁
来源: https://blog.csdn.net/HanLongXia/article/details/120241275

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有