线程(2)

线程同步

当多个控制线程共享同样内存时,须要确保每一个线程看到一致的数据视图。假设每一个线程使用的变量都是其它线程不会读取或改动的,那么就不在一致性问题。

当两个或多个线程试图在同一时间改动同一变量时,也须要进行同步。考虑变量递增操作的情况:增量操作通常分三步:

1.      从内存单元读入寄存器

2.      在寄存器中进行变量值的添加

3.      把新的值写回内存单元

相互排斥量

能够通过使用pthread的相互排斥接口保护数据,确保同一时间仅仅有一个线程訪问数据。相互排斥量从本质上说是一把锁,在訪问资源前对相互排斥量加锁,在訪问完毕后释放相互排斥量上的锁。

对相互排斥量进行加锁以后,不论什么其它试图再次对相互排斥量加锁的线程将会被堵塞直到线程释放该相互排斥锁。

相互排斥变量用pthread_mutex_t数据类型来表示。在使用相互排斥量曾经。必须首先对其进行初始化。能够把它置为PTHREAD_MUTEX_INITIALIZER(仅仅对静态分配的相互排斥量),也能够通过调用pthread_mutex_init函数进行初始化。假设动态分配相互排斥量。那么释放内存前须要调用pthread_mutex_destroy。

用默认属性初始化相互排斥量,仅仅须要把attr设置为NULL。

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *restrict mutex,constpthread_mutexattr_t *restrict attr);

  intpthread_mutex_destroy(pthread_mutex_t *mutex);

,错误返回错误编号。

对相互排斥量进行加锁,须要调用pthread_mutex_lock,假设相互排斥量已经上锁,调用线程将堵塞直到相互排斥量被解锁。

#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock( pthread_mutex_t *mutex );

int pthread_mutex_unlock(pthread_mutex_t *mutex);

,错误返回错误编号。

。否则pthread_mutex_trylock就会失败。不能锁住相互排斥量。而返回EBUSY。

避免死锁

假设线程试图对同一个相互排斥量加锁两次,那么它自身就会陷入死锁状态。

假设程序中使用多个相互排斥量时,假设同意一个线程一直占有第一个相互排斥量,而且试图锁住第二个相互排斥量时处于堵塞状态。可是游泳第二个相互排斥量的线程也试图锁住第一个相互排斥量,这是就会发生死锁。

能够通过小心地控制相互排斥量加锁的顺序来避免死锁的发生。仅仅有一个线程试图以与还有一个线程相反的顺序锁住相互排斥量时,才可能出现死锁。

读写锁

读写锁有三种状态:度模式下加锁状态。写模式下加锁状态,不加锁状态。一次仅仅有一个线程能够占用写模式的读写锁。可是多个线程能够同一时候占用读模式的读写锁。

读写锁很适合于对数据结构读的次数远大于写的情况。读写锁也叫做共享——独占锁。当读写锁以读模式锁住时,它是以共享模式锁住的;当它以写模式锁住时,它是以独占模式锁住的。

与相互排斥量一样,读写锁在使用之前必须初始化。在释放它们底层的内存前必须销毁。

#include <pthread.h>

intpthread_rwlock_init(pthread_rwlock* restrict rwlock, const pthread_rwlockattr_t* restrict attr);

int pthread_rwlock_destroy(pthread_rwlock_t* rwlock);

要在读模式下锁定读写锁,须要调用pthread_rwlock_rdlock;要在写模式下锁定读写锁。须要调用pthread_rwlock_wrlock。无论以何种方式锁住读写锁。都能够调用pthreead_rwlock_unlock进行解锁。

#include <pthread.h>

intpthread_rwlock_rdlock(pthread_rwlock_t* rwlock);

int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock);

int pthread_rwlock_unlock(pthread_rwlock_t* rwlock);

,否则返回错误编号

#include <pthread.h>

int pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock);

int pthread_rwlock_trywrlock(pthread_rwlock_t* rwlock);

条件变量

条件变量是线程可用的还有一种同步机制。

条件变量给多线程提供了一个回合的场所。条件变量与相互排斥量一起使用时,同意线程以无竞争的方式等待特定的条件发生。

条件本身是由相互排斥量保护的。

线程在改变条件状态前必须首先锁住相互排斥量。其它线程在获得相互排斥量之前不会觉察到这样的改变。由于必须锁定相互排斥量以后才干计算条件。

条件变量使用之前必须首先进行初始化,pthread_cond_t数据类型代表的条件变量以两种方式进行初始化。能够把常量PTHREAD_COND_INITIALIZER赋给静态分配的条件变量,可是假设条件变量时动态分配的,能够使用pthread_cond_init函数进行初始化。

在释放底层的内存空间之前。能够使用pthread_cond_destroy函数对条件变量进行去初始化。

#include <pthread.h>

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

int pthread_cond_destroy (pthread_cond_t* cond);

除非须要创建一个非默认属性的条件变量,否则pthread_cond_init函数的attr參数能够设置NULL。

使用pthread_cond_wait等待条件变为真,假设在给定时间内条件不能满足,那么会生成一个代表出错误码的返回值。

intpthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

intpthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, conststruct timespec *abstime)

条件等待pthread_cond_wait()和计时等待pthread_cond_timedwait(),当中计时等待方式假设在给定时刻前条件没有满足。则返回ETIMEOUT。结束等待,当中abstime以与time()系统调用相允许义的绝对时间形式出现。0表示格林尼治时间1970年1月1日0时0分0秒。

不管哪种等待方式。都必须和一个相互排斥锁配合。以防止多个线程同一时候请求pthread_cond_wait()(或pthread_cond_timedwait()。下同)的竞争条件(RaceCondition)。

mutex相互排斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列曾经,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被又一次加锁,以与进入pthread_cond_wait()前的加锁动作相应。

Linux/UNIX线程(2)的更多相关文章

  1. Linux/Unix 线程同步技术之互斥量(1)

    众所周知,互斥量(mutex)是同步线程对共享资源访问的技术,用来防止下面这种情况:线程A试图访问某个共享资源时,线程B正在对其进行修改,从而造成资源状态不一致.与之相关的一个术语临界区(critic ...

  2. Linux/UNIX线程(1)

    线程(1) 本文将介绍怎样使用多个控制线程在单个进程环境中运行多个任务. 一个进程中的全部线程都能够訪问该进程的组成部件(如文件描写叙述符和内存). 线程包含了表示进程内运行环境必须的信息,当中包含进 ...

  3. 学习linux/unix编程方法的建议(转)

    假设你是计算机科班出身,计算机系的基本课程如数据结构.操作系统.体系结构.编译原理.计算机网络你全修过 我想大概可以分为4个阶段,水平从低到高从安装使用=>linux常用命令=>linux ...

  4. Linux Unix 环境变量设置实例

    背景 从第一次写Hello World我们便开始接触环境变量.这最基础的系统设置是必须要掌握的,尤其在是Linux/Unix系统中.比如,哪天某个Java进程出现问题,我们想分析一下其线程堆栈,却发现 ...

  5. 《Linux/Unix系统编程手册》读书笔记7 (/proc文件的简介和运用)

    <Linux/Unix系统编程手册>读书笔记 目录 第11章 这章主要讲了关于Linux和UNIX的系统资源的限制. 关于限制都存在一个最小值,这些最小值为<limits.h> ...

  6. 《Linux/Unix系统编程手册》读书笔记2

    <Linux/Unix系统编程手册>读书笔记 目录 第5章: 主要介绍了文件I/O更深入的一些内容. 原子操作,将一个系统调用所要完成的所有动作作为一个不可中断的操作,一次性执行:这样可以 ...

  7. Linux编程---线程

    首先说一下线程的概念.事实上就是运行在进程的上下文环境中的一个运行流.普通进程仅仅有一条运行流,可是线程提供了多种运行的路径并行的局面. 同一时候,线程还分为核心级线程和用户级线程.主要差别在属于核内 ...

  8. 《Linux/Unix系统编程手册》 时间子系统

    Linux下操作系统编程有两本经典APUE即<Advanced Programming in the UNIX Environment>和TLPI<The Linux Program ...

  9. 《Linux/UNIX系统编程手册》第63章 IO多路复用、信号驱动IO以及epoll

    关键词:fasync_helper.kill_async.sigsuspend.sigaction.fcntl.F_SETOWN_EX.F_SETSIG.select().poll().poll_wa ...

随机推荐

  1. 转载:Logistic回归原理及公式推导

    转载自:AriesSurfer 原文见 http://blog.csdn.NET/acdreamers/article/details/27365941 Logistic回归为概率型非线性回归模型,是 ...

  2. SimpleCV install and "You need the python image library to save by filehandle"

    2015年5月3日 22:15:43 在win7下安装了python.simplecv,试着运行simplecv官网第一个hello world程序结果报错,提示说%python%/lib/site- ...

  3. 完美解决wordpress邮件链接无效的问题

    教程介绍:解决wordpress新用户注册邮件链接无效以及重新设置密码链接无效的问题 解决流程 案例一.用户注册 当用户注册站点时,用户会收到如下注册信: 当用户点击链接时,却发现链接无效: 仔细观察 ...

  4. css弹性盒子

    body元素设置: <body> <div id="wai"> <div class="zi">1</div> ...

  5. AC日记——[USACO5.4]奶牛的电信Telecowmunication 洛谷 P1345

    [USACO5.4]奶牛的电信Telecowmunication 思路: 水题: 代码: #include <cstdio> #include <cstring> #inclu ...

  6. 元组tuple常用方法

    元组tuple的功能类似与列表,元组有的功能,列表都有,列表有的,元组不一定有,下面来看看元组具有的功能:     1.count(self,value) count(self,value)统计元组中 ...

  7. 自动化测试框架Cucumber和Robot Framework的实战对比

    自动化测试框架Cucumber和RobotFramework的实战对比 一.摘要 自动化测试可以快速自动完成大量测试用例,节约巨大的人工测试成本:同时它需要拥有专业开发技能的人才能完成开发,且需要大量 ...

  8. fastadmin iframe 表单提交之后跳转

    controller 对应的那个js文件中添加: define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function($, und ...

  9. 《Android虚拟机》--内存分配策略

    No1: Java在内存分配时会涉及到以下区域: 寄存器:我们在程序中无法控制 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 堆:存放用new产生的数据 静态域:存放在对 ...

  10. SQL必知必会 -------- 通配符、计算字段、函数

    1.LIKE操作符 1.1百分号(%)通配符 SELECT prod_id, prod_name FROM Products WHERE prod_name LIKE 'Fish%' 此例子使用了搜索 ...