线程条件控制实现线程的同步

这篇具有很好参考价值的文章主要介绍了线程条件控制实现线程的同步。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        前面讲了互斥锁,但是总感觉有些功能互斥锁有些不够用。

    条件变量是线程另一可用的同步机制。条件变量给多个线程提供了一个会合的场所。条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定的条件发生。

  条件本身是由互斥量保护的。线程在改变条件状态前必须首先锁住互斥量,其他线程在获得互斥量之前不会察觉到这种改变,因为必须锁定互斥量以后才能计算条件。

条件创建

  条件变量使用之前必须首先初始化,pthread_cond_t数据类型代表的条件变量可以用两种方式进行初始化,可以把常量PTHREAD_COND_INITIALIZER赋给静态分配的条件变量,但是如果条件变量是动态分配的,可以使用pthread_cond_destroy函数对条件变量进行去除初始化。

函数原型

int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);

参数

pthread_cond_t *restrict cond:条件的地址

const pthread_condattr_t *restrict attr:条件的参数,一般为NULL就可以

返回值

若成功返回0,否则返回错误编号

条件销毁

函数原型

int pthread_cond_destroy(pthread_cond_t *cond);

参数

pthread_cond_t *restrict cond:条件的地址

返回值

若成功返回0,否则返回错误编号

条件触发

这两个函数可以用于通知线程条件已经满足。pthread_cond_signal函数将唤醒等待该条件的某个线程,而pthread_cond_broadcast函数将唤醒等待该条件的所有进程。

注意一定要在改变条件状态以后再给线程发信号。

函数原型

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

返回值

若成功返回0,否则返回错误编号

条件等待

pthread_cond_wait等待条件变为真。如果在给定的时间内条件不能满足,那么会生成一个代表一个出错码的返回变量。传递给pthread_cond_wait的互斥量对条件进行保护,调用者把锁住的互斥量传给函数。函数把调用线程放到等待条件的线程列表上,然后对互斥量解锁,这两个操作都是原子操作。这样就关闭了条件检查和线程进入休眠状态等待条件改变这两个操作之间的时间通道,这样线程就不会错过条件的任何变化。pthread_cond_wait返回时,互斥量再次被锁住。

函数原型

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);

参数

pthread_cond_t *restrict cond:条件的地址

pthread_mutex_t *restrict mutex:互斥锁的地址

cond struct timespec *restrict timeout:timeout指定了等待的时间,它是通过timespec结果指定。

返回值

若成功返回0,否则返回错误编号

示例:

当 t2 线程将g_data加到3时,t1 线程才开始运行。

#include <stdio.h>
#include <pthread.h>
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); 
//int pthread_mutex_destroy(pthread_mutex_t mutex);
//int pthread_mutex_lock(pthread_mutex_t mutex);
//int pthread_mutex_trylock(pthread_mutex_t mutex);
//int pthread_mutex_unlock(pthread_mutex_t mutex)
//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
//int pthread_cond_destroy(pthread_cond_t cond);
//int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
//int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);
//int pthread_cond_signal(pthread_cond_t cond);
//int pthread_cond_broadcast(pthread_cond_t cond);

pthread_mutex_t mutex;
pthread_cond_t cond;
int g_data=0;

void *func1(void *arg)
{
        printf("t1:%ld thread is creart\n",(unsigned long)pthread_self());
        printf("t1:param is %d\n",*((int *)arg));
        pthread_mutex_lock(&mutex);
        while(1)
        {
                pthread_cond_wait(&cond,&mutex);
                if(g_data==3)
                {
                        printf("ti run==================\n");
                }
                printf("t1:%d\n",g_data);
                g_data=0;
                sleep(1);

        }

}

void *func2(void *arg)
{
        printf("t2:%ld thread is creart\n",(unsigned long)pthread_self());
        printf("t2:param is %d\n",*((int *)arg));
        while(1)
        {
                printf("t2:%d\n",g_data);
                pthread_mutex_lock(&mutex);
                g_data++;
                if(g_data ==3 )
                {
                        pthread_cond_signal(&cond);
                }
                pthread_mutex_unlock(&mutex);
                sleep(1);
        }
}

int main()
{
        int param=100;
        char *pret=NULL;
        int ret1;
        int ret2;
        pthread_t t1;
        pthread_t t2;

        pthread_mutex_init(&mutex,NULL);
        pthread_cond_init(&cond,NULL);

        ret1=pthread_create(&t1, NULL,func1, (void *)&param);
        ret2=pthread_create(&t1, NULL,func2, (void *)&param);
        if(ret1 == 0)
        {
                printf("main:create t1 successed\n");
        }

        if(ret2 == 0)
        {
                printf("main:create t2 successed\n");
        }


        pthread_join(t1,NULL);
        pthread_join(t2,NULL);

        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
        return 0;
}

线程条件控制实现线程的同步,Linux系统编程——线程,linux,c语言

可以看到以上代码,只要g_data加到3 就运行t1线程,并把g_data置为0,然后退出t1线程。

以上代码用的都是条件、互斥锁的动态初始化 pthread_cond_init(&cond,NULL); pthread_mutex_init(&mutex,NULL);,还可以使用宏来进行静态初始化 pthread_cond_t = PTHREAD_INITIALIZER; pthread_mutex_t = PTHREAD_MUTEX_INITIALIZER;

PS代码测试技巧

int main(int argc ,char **argv)
{

        int i;
        int cnt=atoi(argv[1]);
        for(i=0;i<cnt;i++)
        {
                system("./test");
        }
        return 0;
}

线程条件控制实现线程的同步,Linux系统编程——线程,linux,c语言

./a.out 10 >> test.ret.txt &
等测试完毕后可以在test.ret.txt里查看测试的结果,&代表的是后台运行。文章来源地址https://www.toymoban.com/news/detail-744859.html

到了这里,关于线程条件控制实现线程的同步的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《Linux操作系统编程》 第十章 线程与线程控制: 线程的创建、终止和取消,detach以及线程属性

    🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬

    2024年02月11日
    浏览(80)
  • 【Linux】线程同步 -- 条件变量 | 生产者消费者模型 | 自旋锁 |读写锁

    举一个例子: 学生去超市消费的时候,与厂家生产的时候,两者互不相冲突。 生产的过程与消费的过程 – 解耦 临时的保存产品的场所(超时) – 缓冲区 模型总结“321”原则: 3种关系:生产者和生产者(互斥),消费者和消费者(互斥),生产者和消费者(互斥[保证共享资

    2024年02月14日
    浏览(28)
  • 一文搞定Linux线程间通讯 / 线程同步方式-互斥锁、读写锁、自旋锁、信号量、条件变量、信号等等

    目录 线程间通讯 / 线程同步方式 锁机制 互斥锁(Mutex) 读写锁(rwlock) 自旋锁(spin) 信号量机制(Semaphore) 条件变量机制 信号(Signal) 线程间通讯 / 线程同步方式 p.s 以下有很多段落是直接引用,没有使用 markdown 的 “引用” 格式,出处均已放出。 参考 / 引用: 100as

    2024年02月10日
    浏览(31)
  • 【Linux学习】多线程——同步 | 条件变量 | 基于阻塞队列的生产者消费者模型

    🐱作者:一只大喵咪1201 🐱专栏:《Linux学习》 🔥格言: 你只管努力,剩下的交给时间! 以生活中消费者生产者为例: 生活中,我们大部分人都扮演着消费者的角色,会经常在超市买东西,比如买方便面,而超市的方便面是由供应商生成的。所以我们就是消费者,供应商

    2024年02月05日
    浏览(37)
  • 【Linux C | 多线程编程】线程同步 | 信号量(无名信号量) 及其使用例子

    😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭 🤣本文内容🤣:🍭介绍 🍭 😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭 ⏰发布时间⏰: 本文未经允许,不得转发!!!

    2024年04月26日
    浏览(27)
  • Linux【实操篇】—— Shell 编程入门、变量、运算符、条件判断、流程控制

    目录 一、Shell 编程入门 1. 认识 Shell 2. Shell 脚本的创建与执行         二、Shell 变量 1. 系统变量和自定义变量 2. 变量的基本规则 3. 设置环境变量 4. 位置参数变量 5. 预定义变量 三、运算符 四、条件判断 五、流程控制 1. if 语句 2. case 语句 3. for 循环 4. while 循环 六、rea

    2024年02月03日
    浏览(31)
  • Linux系统Shell脚本编程之条件语句

    Shell 环境根据命令执行后的返回状态值 \\\" $? \\\" 来判断是否执行成功,当返回值为0时表示成功,否则表示失败或异常(非0值)。 使用专门的测试工具 test 命令,可以对特定条件进行测试,并根据返回值(值为0)来判断是否成立。 test命令格式 文件测试指的是根据给定的路径名

    2024年01月25日
    浏览(60)
  • linux系统编程(7)--线程

    在许多经典的操作系统教科书中,总是把进程定义为程序的执行实例,它并不执行什么, 只是维护应用程序所需的各种资源,而线程则是真正的执行实体。 所以,线程是轻量级的进程(LWP:light weight process),在Linux环境下线程的本质仍是进程。为了让进程完成一定的工作,进

    2023年04月08日
    浏览(23)
  • 系统编程之高效同步机制:条件变量

    以下内容为本人的学习笔记,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/zy6Dmo_b3xMPPEO3HNxuuw 有一段时间没碰条件变量【condition variable】,快忘了它到底是啥。大概记得,之前是用来写底层接口,辅助实现安全的生产消费模式等等。 下面让我们来探

    2024年02月09日
    浏览(44)
  • Linux系统编程5(线程概念详解)

    线程同进程一样都是OS中非常重要的部分,线程的应用场景非常的广泛,试想我们使用的视频软件,在网络不是很好的情况下,通常会采取下载的方式,现在你很想立即观看,又想下载,于是你点击了下载并且在线观看。学过进程的你会不会想,视频软件运行后在OS内形成一个

    2024年02月10日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包