- 浏览: 141116 次
文章分类
最新评论
线程的同步对象和线程一样也具有属性,上一节介绍了线程属性,本节将讨论线程的同步属性,包括互斥量属性、读写锁属性、条件变量属性和屏障属性。
对比线程属性,互斥量属性也有一组操作函数。
pthread_mutexattr_init 函数会用默认的互斥量属性初始化 pthread_mutexattr_t 结构,pthread_mutexattr_destroy 则用来反初始化。
值得注意的 3 个属性是:进程共享属性、健壮属性以及类型属性。POSIX.1 中,进程共享属性是可选的,可以通过检查是否定义了 _POSIX_THREAD_PROCESS_SHARED 符号或把 _SC_THREAD_PROCESS_SHARED 参数传给 sysconf 函数来判断平台是否支持该属性。
函数 pthread_mutexattr_getpshared 和 pthread_mutexattr_setpshared 可以用来查询和修改进程共享属性。在进程中,默认多个线程可以访问同一个同步对象,此时的进程共享互斥量属性需设置为 PTHREAD_PROCESS_PRIVATE。如果进程共享互斥量属性设置为 PTHREAD_PROCESS_SHARED,则从多个进程彼此之间共享的内存数据块中分配的互斥量就可以用于这些进程的同步。
函数 pthread_mutexattr_getrobust 和 pthread_mutexattr_setrobust 可分别用来获取和设置互斥量健壮属性的值。互斥量健壮属性与在多个进程间共享的互斥量有关。这意味着当持有互斥量的进程终止时,需要解决互斥量状态恢复的问题。这种情况发生时,互斥量处于锁定状态,恢复起来很困难,其它阻塞在这个锁的进程将会一直阻塞下去。
健壮属性取值有两种可能的情况,默认值是 PTHREAD_MUTEX_STALLED,这表示持有互斥量的进程终止时不需要采取特别的动作。这种情况下,使用互斥量后的行为是未定义的,等待该互斥量解锁的应用程序会被有效地“拖住”。另一个值是 PTHREAD_MUTEX_ROBUST,这个值将导致线程调用 pthread_mutex_lock 获取锁,而该锁被另一个进程持有,但它终止时并没有对其进行解锁,此时线程会阻塞,从 pthread_mutex_lock 返回的值为 EOWNERDEAD 而不是 0。应用程序可以通过该值获知,若有可能(要保护状态的细节以及如何进行恢复会因不同的应用程序而异),不管它们保护的互斥量状态如何,都需要进行恢复。
如果应用状态无法恢复,在线程对互斥量解锁以后,该互斥量将处于永久不可用状态。为避免这样的问题,线程就可以调用 pthread_mutex_consistent 函数来指明与该互斥量相关的状态在互斥量解锁之前是一样的。如果线程没有先调用该函数就对互斥量进行了解锁,那么其他试图获取该互斥量的阻塞线程就会得到错误码 ENOTRECOVERABLE。若发生这种情况,互斥量将不再可用。线程通过提前调用该函数,就能让互斥量正常工作,这样它就可以持续被使用。
pthread_mutexattr_gettype 和 pthread_mutexattr_settype 函数可以获取和修改互斥量类型属性。类型互斥量属性控制着互斥量的锁定特性。POSIX.1 定义了 4 种类型。
1、PTHREAD_MUTEX_NORMAL:标准互斥量类型,不做任何特殊的错误检查或死锁检测。
2、PTHREAD_MUTEX_ERRORCHECK:此互斥量类型提供错误检查。
3、PTHREAD_MUTEX_RECURSIVE:此互斥量类型允许同一线程在互斥量解锁之前对互斥量进行多次加锁。递归互斥量维护锁的计数,在解锁次数和加锁次数不相同时不会释放锁。
4、PTHREAD_MUTEX_DEFAULT:此互斥量类型可以提供默认特性和行为。操作系统在实现它的时候可以把这种类型自由地映射到其他互斥量类型中的一种。
这 4 种类型的行为如下表所示。其中,“不占用时解锁”这一栏指的是,一个线程对被另一个线程加锁的互斥量进行解锁的情况;“在已解锁时解锁”指的是,一个线程对已经解锁的互斥量进行解锁的情况。
介绍了互斥量属性后,其他同步属性就好理解了,它们也支持一组类似的函数,可对比互斥量属性进行理解。
对于读写锁,它支持的唯一属性是进程共享属性,所以它有这样几个函数。
条件变量支持进程共享属性和时钟属性。前者控制着条件变量是可以被单进程的多个线程使用,还是可以被多进程的线程使用;后者则控制计算 pthread_cond_timedwait 函数的超时参数时采用的是哪个时钟。pthread_condattr_getclock 和 pthread_condattr_setclock 函数可以用来获取和修改用于 pthread_cond_timedwait 的时钟 ID。
屏障也只支持进程共享属性,它控制着屏障是可以被多进程的线程使用,还是只能被初始化屏障的进程内的多线程使用。它有这样一组函数。
对比线程属性,互斥量属性也有一组操作函数。
#include <pthread.h> int pthread_mutexattr_init(pthread_mutexattr_t *attr); int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared); int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared); int pthread_mutexattr_getrobust(const pthread mutexattr_t *restrict attr, int *restrict robust); int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robust); int pthread_mutex_consistent(pthread_mutex_t *mutex); int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type); int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); /* 所有函数的返回值:若成功,返回 0;否则,返回错误编号 */
pthread_mutexattr_init 函数会用默认的互斥量属性初始化 pthread_mutexattr_t 结构,pthread_mutexattr_destroy 则用来反初始化。
值得注意的 3 个属性是:进程共享属性、健壮属性以及类型属性。POSIX.1 中,进程共享属性是可选的,可以通过检查是否定义了 _POSIX_THREAD_PROCESS_SHARED 符号或把 _SC_THREAD_PROCESS_SHARED 参数传给 sysconf 函数来判断平台是否支持该属性。
函数 pthread_mutexattr_getpshared 和 pthread_mutexattr_setpshared 可以用来查询和修改进程共享属性。在进程中,默认多个线程可以访问同一个同步对象,此时的进程共享互斥量属性需设置为 PTHREAD_PROCESS_PRIVATE。如果进程共享互斥量属性设置为 PTHREAD_PROCESS_SHARED,则从多个进程彼此之间共享的内存数据块中分配的互斥量就可以用于这些进程的同步。
函数 pthread_mutexattr_getrobust 和 pthread_mutexattr_setrobust 可分别用来获取和设置互斥量健壮属性的值。互斥量健壮属性与在多个进程间共享的互斥量有关。这意味着当持有互斥量的进程终止时,需要解决互斥量状态恢复的问题。这种情况发生时,互斥量处于锁定状态,恢复起来很困难,其它阻塞在这个锁的进程将会一直阻塞下去。
健壮属性取值有两种可能的情况,默认值是 PTHREAD_MUTEX_STALLED,这表示持有互斥量的进程终止时不需要采取特别的动作。这种情况下,使用互斥量后的行为是未定义的,等待该互斥量解锁的应用程序会被有效地“拖住”。另一个值是 PTHREAD_MUTEX_ROBUST,这个值将导致线程调用 pthread_mutex_lock 获取锁,而该锁被另一个进程持有,但它终止时并没有对其进行解锁,此时线程会阻塞,从 pthread_mutex_lock 返回的值为 EOWNERDEAD 而不是 0。应用程序可以通过该值获知,若有可能(要保护状态的细节以及如何进行恢复会因不同的应用程序而异),不管它们保护的互斥量状态如何,都需要进行恢复。
如果应用状态无法恢复,在线程对互斥量解锁以后,该互斥量将处于永久不可用状态。为避免这样的问题,线程就可以调用 pthread_mutex_consistent 函数来指明与该互斥量相关的状态在互斥量解锁之前是一样的。如果线程没有先调用该函数就对互斥量进行了解锁,那么其他试图获取该互斥量的阻塞线程就会得到错误码 ENOTRECOVERABLE。若发生这种情况,互斥量将不再可用。线程通过提前调用该函数,就能让互斥量正常工作,这样它就可以持续被使用。
pthread_mutexattr_gettype 和 pthread_mutexattr_settype 函数可以获取和修改互斥量类型属性。类型互斥量属性控制着互斥量的锁定特性。POSIX.1 定义了 4 种类型。
1、PTHREAD_MUTEX_NORMAL:标准互斥量类型,不做任何特殊的错误检查或死锁检测。
2、PTHREAD_MUTEX_ERRORCHECK:此互斥量类型提供错误检查。
3、PTHREAD_MUTEX_RECURSIVE:此互斥量类型允许同一线程在互斥量解锁之前对互斥量进行多次加锁。递归互斥量维护锁的计数,在解锁次数和加锁次数不相同时不会释放锁。
4、PTHREAD_MUTEX_DEFAULT:此互斥量类型可以提供默认特性和行为。操作系统在实现它的时候可以把这种类型自由地映射到其他互斥量类型中的一种。
这 4 种类型的行为如下表所示。其中,“不占用时解锁”这一栏指的是,一个线程对被另一个线程加锁的互斥量进行解锁的情况;“在已解锁时解锁”指的是,一个线程对已经解锁的互斥量进行解锁的情况。
介绍了互斥量属性后,其他同步属性就好理解了,它们也支持一组类似的函数,可对比互斥量属性进行理解。
对于读写锁,它支持的唯一属性是进程共享属性,所以它有这样几个函数。
#include <pthread.h> int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, int *restrict pshared); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared); /* 所有函数的返回值:若成功,返回 0;否则,返回错误编号 */
条件变量支持进程共享属性和时钟属性。前者控制着条件变量是可以被单进程的多个线程使用,还是可以被多进程的线程使用;后者则控制计算 pthread_cond_timedwait 函数的超时参数时采用的是哪个时钟。pthread_condattr_getclock 和 pthread_condattr_setclock 函数可以用来获取和修改用于 pthread_cond_timedwait 的时钟 ID。
#include <pthread.h> int pthread_condattr_init(pthread_condattr_t *attr); int pthread_condattr_destroy(pthread_condattr_t *attr); int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared); int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); int pthread_condattr_getclock(const pthread_condattr_t *restrict attr, clockid_t *restrict clock_id); int pshared_condattr_setclock(pshared_condattr_t *attr, clockid_t clock_id); /* 所有函数的返回值:若成功,返回 0;否则,返回错误编号 */
屏障也只支持进程共享属性,它控制着屏障是可以被多进程的线程使用,还是只能被初始化屏障的进程内的多线程使用。它有这样一组函数。
#include <pthread.h> int pthread_barrierattr_init(pthread_barrierattr_t *attr); int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, int *restrict pshared); int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared); /* 所有函数的返回值:若成功,返回 0;否则,返回错误编号 */
发表评论
-
打开伪终端设备
2018-07-09 20:50 1249在伪终端概述一节中已对 PTY进行了初步的介绍。尽管 ... -
伪终端概述
2018-06-02 11:05 1538伪终端就是指,一个应用程序看上去像一个终端,但事实上它 ... -
终端窗口大小和 termcap
2018-05-29 22:39 792多数 UNIX 系统都提供了一种跟踪当前终端窗口大小的 ... -
终端规范模式和非规范模式
2018-05-29 00:25 944终端规范模式很简单:发一个读请求,当一行已经输入后,终 ... -
终端标识
2018-05-23 11:18 567尽管控制终端的名字在多数 UNIX 系统上都是 /de ... -
波特率和行控制函数
2018-05-22 07:53 935虽然大多数终端设 ... -
终端属性和选项标志
2018-05-20 07:40 707tcgetattr 和 tcsetattr ... -
终端特殊输入字符
2018-05-17 06:33 810终端支持下表所示的特殊输入字符。 为了更改 ... -
终端 I/O 综述
2018-05-10 07:56 433终端设备可认为是由内核中的终端驱动程序控制的。每个终端 ... -
POSIX 信号量
2018-05-09 00:03 575在XSI IPC通信之信 ... -
XSI IPC 通信之共享存储
2018-04-25 07:18 944在XSI IPC通信之消息队列和XSI IPC通信之信 ... -
XSI IPC通信之信号量
2018-04-17 23:38 612在XSI IPC通信之消 ... -
XSI IPC通信之消息队列
2018-04-15 10:54 490消息队列是消息的链接表,存储在内核中,由消息队列标识符 ... -
XSI IPC 相似特征介绍
2018-02-08 23:48 481有 3 种称作 XSI IPC ... -
IPC 通信之 FIFO
2018-02-06 22:55 413FIFO 也被称为命名管道,未命名的管道只能在两个相关 ... -
IPC 通信之管道
2018-01-30 22:22 383管道是 UNIX 系统 IPC 的最古老但也是最常用的 ... -
readv/writev 函数及存储映射 I/O
2018-01-19 00:57 879readv 和 writev 函数可用于在一次函数调用 ... -
POSIX 异步 I/O
2018-01-16 21:33 451POSIX 异步 I/O 接口为对不同类型的文件进行异 ... -
fcntl 记录锁
2018-01-06 23:48 588记录锁的功能是:当有进程正在读或修改文件的某个部分时, ... -
守护进程惯例
2018-01-06 23:52 433UNIX 系统中,守护进程遵循下列通用惯例。 ...
相关推荐
在C#编程中,线程同步是一个至关重要的概念,特别是在多线程环境下,它用于控制多个线程对共享资源的访问,确保数据的一致性和程序的正确性。本篇文章将详细探讨`AutoResetEvent`这一线程同步工具,并通过一个DEMO来...
本文将深入探讨iOS线程管理,特别是线程的创建和线程同步,这些都是开发者需要掌握的基本知识。 首先,我们来理解一下线程的概念。线程是程序执行的最小单位,一个进程可以有多个线程并行执行,这样可以充分利用...
参APUE.12.4同步属性 1. 静态初始化:如果互斥锁 mutex 是静态分配的(定义在全局,或加了static关键字修饰),可以直接使用宏进行初始化。e.g. pthead_mutex_t muetx = PTHREAD_MUTEX_INITIALIZER; 2. 动态初始化...
本实验旨在深入理解线程与进程的概念,并通过实践操作掌握线程同步的基本方法。同时,本实验还将探讨在Windows环境下如何根据具体需求选择使用进程或线程。 #### 二、实验环境搭建 本实验在**Windows XP**环境下...
理解它们的工作原理,掌握线程同步、前后台线程的概念,以及如何创建有参和无参线程,对于编写高效、稳定的多线程程序至关重要。在实际开发中,结合这些理论知识,我们可以设计出满足各种需求的线程模型,从而提高...
Java多线程同步是编程中一个非常重要的概念,特别是在并发编程中,用于解决多个线程访问共享资源时可能引发的数据不一致问题。本实例通过一个简单的火车票售票系统来演示同步机制的应用。 在这个实例中,我们创建了...
"C# 多线程同步终止" C# 中的多线程编程是非常重要的一部分,特别是在需要高性能和高并发的应用程序中。然而,多线程编程也带来了同步和终止的问题。在这篇文章中,我们将讨论 C# 中如何让主线程等待子线程终止,...
代码中给出了一种方式,去同步字符串,线程携带同一个字符串进入同步方法中,会阻塞,非同一个字符串不会阻塞,所以我们可以考虑用账户名称、或一些账户独有不会重复的属性来进行代码块同步,这样可最大程度的提高...
Delphi提供了各种同步对象,如TCriticalSection、TSemaphore、TMutex等,来实现线程同步。例如,TCriticalSection用于在多线程中保护临界区,确保同一时间只有一个线程能进入该区域。使用TryEnterCriticalSection和...
本篇文章将深入探讨在使用Hibernate时可能会遇到的线程同步问题,以及 Hibernate 中的 session.get() 和 session.load() 方法的异同。 一、Hibernate的并发控制 在多线程环境下,多个线程同时访问和修改数据库记录...
本文将深入探讨多线程编程中的线程同步概念,以及在VC++环境下如何使用MFC(Microsoft Foundation Classes)进行线程同步。 线程同步是为了防止多个线程同时访问共享资源,导致数据不一致或引发竞态条件。竞态条件...
"C# 多线程同步问题解决" C# 中的多线程机制是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务。这可以提高 CPU 的利用率,因为任何一个程序员都不希望自己的程序很多时候没事...
### 线程和线程同步学习 #### 一、线程概述 在现代软件开发中,特别是使用C#进行编程时,理解线程的概念及其重要性是非常关键的。线程是程序执行流程中的最小单位,是进程的一部分,能够并发执行。在C#中,线程...
在这个"swift NSThread线程同步买票小例子"中,我们将深入理解如何使用NSThread进行线程同步,以及在并发编程中遇到的一些关键概念。 首先,线程同步是并发编程中的一个重要概念,它的目的是避免多个线程同时访问...
2. **线程同步与互斥**:在多线程环境中,为了保证数据的一致性,线程之间需要进行同步,如使用锁(互斥锁、读写锁等)或信号量。 3. **线程栈**:每个线程都有自己独立的栈空间,用于存储局部变量和函数调用信息。...
操作系统实验三 - 线程同步 实验的目标是让学生深入理解和掌握Linux环境下多线程编程以及线程同步的原理和方法。在这个实验中,学生需要编写一个模拟火车售票系统的程序,该系统有三个售票窗口,总共销售十张票。...
C#提供了多种机制来实现线程同步,包括lock关键字、Monitor、同步事件和等待句柄以及Mutex类。这些机制的主要目标是避免竞态条件,保证并发执行的线程能够正确地访问和修改共享数据。 首先,我们来看lock关键字。...
线程同步解析是多线程编程中的一个核心概念,它主要关注如何在多个线程同时访问共享资源时,避免数据不一致性和竞态条件等问题。本文将深入探讨线程同步的基本原理、Java中的线程同步机制,特别是`synchronized`...