`
ccbobocat
  • 浏览: 20180 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

[导入]多线程编程学习笔记—条件变量

阅读更多

一、什么是条件变量

       与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。

       条件变量使我们可以睡眠等待某种条件出现。条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。

条 件的检测是在互斥锁的保护下进行的。如果一个条件为假,一个线程自动阻塞,并释放等待状态改变的互斥锁。如果另一个线程改变了条件,它发信号给关联的条件 变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。如果两进程共享可读写的内存,条件变量可以被用来实现这两进程间的线程同步。

       使用条件变量之前要先进行初始化。可以在单个语句中生成和初始化一个条件变量如:

pthread_cond_t my_condition=PTHREAD_COND_INITIALIZER;(用于进程间线程的通信)。

也可以利用函数pthread_cond_init动态初始化。

 

二、条件变量函数

1

名称:

pthread_cond_init

目标:

条件变量初始化

头文件:

#include < pthread.h>

函数原形:

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

参数:

cptr  条件变量

attr  条件变量属性

返回值:

成功返回0,出错返回错误编号。

     

 

 

 

 

 

  pthread_cond_init函数可以用来初始化一个条件变量。他使用变量attr所指定的属性来初始化一个条件变量,如果参数attr为空,那么它将使用缺省的属性来设置所指定的条件变量。

 

2.

名称:

pthread_cond_destroy

目标:

条件变量摧毁

头文件:

#include < pthread.h>

函数原形:

int pthread_cond_destroy(pthread_cond_t *cond);

参数:

cptr  条件变量

返回值:

成功返回0,出错返回错误编号。

      

 

 

 pthread_cond_destroy函数可以用来摧毁所指定的条件变量,同时将会释放所给它分配的资源。调用该函数的进程也并不要求等待在参数所指定的条件变量上。

 

3.

名称:

pthread_cond_wait/pthread_cond_timedwait

目标:

条件变量等待

头文件:

#include < pthread.h>

函数原形:

int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);

int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t mytex,const struct timespec *abstime);

参数:

cond 条件变量

mutex 互斥锁

返回值:

成功返回0,出错返回错误编号。

      

 

 

 

 

 

 

第一个参数*cond是指向一个条件变量的指针。第二个参数*mutex则是对相关的互斥锁的指针。函数pthread_cond_timedwait函数类型与函数pthread_cond_wait,区别在于,如果达到或是超过所引用的参数*abstime,它将结束并返回错误ETIME.pthread_cond_timedwait函数的参数*abstime指向一个timespec结构。该结构如下:

typedef struct timespec{

       time_t tv_sec;

       long tv_nsex;

}timespec_t;

 

3.

名称:

pthread_cond_signal/pthread_cond_broadcast

目标:

条件变量通知

头文件:

#include < pthread.h>

函数原形:

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

参数:

cond 条件变量

返回值:

成功返回0,出错返回错误编号。

      

 

 

 

 

 参数*cond是对类型为pthread_cond_t 的一个条件变量的指针。当调用pthread_cond_signal时一个在相同条件变量上阻塞的线程将被解锁。如果同时有多个线程阻塞,则由调度策略确定接收通知的线程。如果调用pthread_cond_broadcast,则将通知阻塞在这个条件变量上的所有线程。一旦被唤醒,线程仍然会要求互斥锁。如果当前没有线程等待通知,则上面两种调用实际上成为一个空操作。如果参数*cond指向非法地址,则返回值EINVAL

 

下面是一个简单的例子,我们可以从程序的运行来了解条件变量的作用。

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

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*
初始化互斥锁*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*
初始化条件变量*/

void *thread1(void *);
void *thread2(void *);

int i=1;
int main(void)
{
    pthread_t t_a;
    pthread_t t_b;

    pthread_create(&t_a,NULL,thread2,(void *)NULL);/*
创建进程t_a*/
    pthread_create(&t_b,NULL,thread1,(void *)NULL); /*
创建进程t_b*/
    pthread_join(t_b, NULL);/*
等待进程t_b结束*/
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    exit(0);
}

void *thread1(void *junk)
{
    for(i=1;i<=9;i++)
    {
        pthread_mutex_lock(&mutex);/*
锁住互斥量*/
        if(i%3==0)
             pthread_cond_signal(&cond);/*
条件改变,发送信号,通知t_b进程*/
        else       
             printf("thead1:%d\n",i);
        pthread_mutex_unlock(&mutex);/*
解锁互斥量*/

sleep(1);
}

}

void *thread2(void *junk)
{
    while(i<9)
    {
        pthread_mutex_lock(&mutex);

if(i%3!=0)
            pthread_cond_wait(&cond,&mutex);/*
等待*/
        printf("thread2:%d\n",i);
        pthread_mutex_unlock(&mutex);

sleep(1);
}

}

程序创建了2个新线程使他们同步运行,实现进程t_b打印20以内3的倍数,t_a打印其他的数,程序开始线程t_b不满足条件等待,线程t_a运行使a循环加1并打印。直到i3的倍数时,线程t_a发送信号通知进程t_b,这时t_b满足条件,打印i值。

下面是运行结果:

#cc –lpthread –o cond cond.c

#./cond

thread1:1

thread1:2

thread2:3

thread1:4

thread1:5

thread2:6

thread1:7

thread1:8

thread2:9


文章来源:http://blog.163.com/ccbobo_cat/blog/static/3209946220095235658763
分享到:
评论

相关推荐

    Python自学笔记 Python核心编程第二版学习笔记 很详细的学习笔记 建议收藏 共148页.pdf

    十五至十七章涉及网络编程、网络客户端编程和多线程编程,分别讲解如何使用Python进行网络通信、创建网络客户端应用以及利用多线程实现并发执行。 总的来说,这份笔记全面覆盖了Python的核心概念和技术,是学习和...

    Go语言学习笔记

    Go语言学习笔记的知识点涵盖广泛,它从基础的语法到高级的并发编程,再到源码的剖析,全面介绍了Go语言的特点和编程技巧。以下是根据所提供的文件内容提取的知识点: 1. Go语言基础:Go是一种静态类型编程语言,...

    go学习笔记-文档-文档

    本文档集合了关于Go语言的学习笔记,旨在帮助读者全面理解并掌握Go语言的核心概念、语法特性以及实际应用。 一、基础语法 Go语言的语法简洁明了,易于上手。它采用了C风格的语法,但增加了诸如类型推断(Type ...

    ES6 学习笔记.pdf

    通过这份学习笔记,我们可以看到ES6作为一个重要的JavaScript版本更新,它所引入的新特性极大推动了JavaScript的发展,使之更加成熟和强大,尤其在异步编程和模块化方面,为前端开发提供了更多现代化的解决方案。

    Go 学习笔记 第三版

    Go语言的并发编程能力是其一大亮点,它通过goroutine来实现,goroutine是一种轻量级的线程,由Go语言运行时调度,与操作系统线程相比,它具有更低的启动开销和上下文切换成本。使用关键字go可以启动一个goroutine...

    java基础核心学习笔记

    本学习笔记将深入探讨Java的核心概念,帮助你建立坚实的基础。 1. **Java语法基础** - 变量与数据类型:Java支持基本数据类型(如int、float、char)以及引用数据类型(如类、接口、数组)。变量声明必须指定类型...

    java核心编程课堂笔记

    - **多线程**:内置多线程支持,方便编写并发程序。 - **动态性**:Java 支持动态加载类,适应不断变化的环境。 2. **Java 基础元素**: - **关键字**:如 "public"、"class"、"static" 和 "void",它们有特定的...

    java学习笔记基于法练习

    4. 多线程:Java支持多线程编程,可以同时执行多个任务,提高程序效率。 二、Java语法基础 1. 数据类型:Java分为两种数据类型:基本类型(如int、char、boolean)和引用类型(如类、接口、数组)。基本类型直接...

    良葛格java jdk 5.0学习笔记

    10. **并发编程改进**:Java 5.0引入了`java.util.concurrent`包,包含了许多新的并发工具类,如`ExecutorService`、`Future`、`Callable`和`CyclicBarrier`等,帮助开发者更高效地编写多线程代码。 《良葛格Java ...

    JAVA学习笔记(完整版)

    多线程在JAVA中也占据重要地位。通过Thread类和Runnable接口,开发者可以创建并管理多个执行线程,实现并发执行。同步机制,如synchronized关键字和wait/notify机制,保证了线程安全。 最后,JAVA EE(企业版)是...

    java实战经典学习笔记

    ### Java实战经典学习笔记知识点概览 #### 一、Java概述及开发环境搭建 - **Java概述** - Java是一种广泛使用的高级编程语言,由Sun Microsystems于1995年发布。 - Java的设计目标是“一次编写,到处运行”,这...

    B站黑马程序员Python教程学习笔记.zip

    Python是一种高级、通用的编程语言,以其简洁、易读的语法而闻名,被广泛应用于网络爬虫、数据分析、机器学习、人工智能等多个领域。在B站黑马程序员的Python教程中,你将深入理解Python的基础概念,包括: 1. **...

    Python 语言学习笔记.zip

    从基础开始,Python的学习需要掌握其基本语法,包括变量定义、数据类型(如整型、浮点型、字符串、布尔型以及列表、元组、字典、集合等复合类型)、运算符(算术、比较、逻辑、成员、身份)以及流程控制(条件语句、...

    良葛格Java JDK 5[1].0学习笔记

    Java JDK 5.0是Java开发工具包的一个重要版本,由Sun Microsystems(后被Oracle收购)于2004年发布。...通过阅读“良葛格Java JDK 5.0学习笔记”,读者可以系统地学习和掌握这些内容,进一步提升自己的Java编程技能。

    前端基础学习笔记,pdf

    JavaScript在浏览器中的执行由JavaScript引擎负责,如Chrome的V8引擎,它采用单线程模型但通过事件循环和异步处理模拟多线程效果。 在JavaScript中,变量是存储数据的容器,有原始类型(如字符串、数字、布尔、null...

    java学习笔记,全程

    7. **多线程** - 线程的概念:解释并发与并行,理解线程的生命周期。 - 创建线程:通过Thread类和Runnable接口创建线程。 - 线程同步:学习synchronized关键字、wait()、notify()和notifyAll()的使用,防止数据...

    良葛格Java JDK 5.0学习笔记

    12. **并发工具类(Concurrent Utilities)**:如`java.util.concurrent`包,提供了线程安全的数据结构和并发控制机制,如Semaphore、CyclicBarrier、CountDownLatch等,简化了多线程编程。 良葛格的学习笔记中可能...

    c#学习笔记.txt

    c#学习笔记(1) 51099在线学习网发布 文章来源:网络收集 发布时间:2006-05-25 字体: [大 中 小] 51099在线学习网 http://www.51099.com 1, 结构(struct) 与 类(class) [attributes] [modifiers] struct ...

Global site tag (gtag.js) - Google Analytics