线程篇——线程同步对象-互斥锁API

说明
  本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
  QQ 群 号:513683159 【相互学习】
内容来源
  《多线程编程指南》

互斥锁

  作用:可使线程按顺序执行。
    ①确保一次只有一个线程执行代码的临界段来同步多个线程。
    ②保护单线程代码。
  使用:设置在应用程序开头某处,以便查找和修改。

初始化互斥锁属性对象:pthread_mutexattr_init ()

  1.函数功能:可将与互斥锁属性对象__attr相关联的属性初始化为其缺省值。在执行过程中,线程系统会为每个属性对象分配存储空间。

项目 说明
函数原型 extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr) __THROW __nonnull ((1));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    ENOMEM:内存不足,无法初始化互斥锁属性对象。

销毁互斥锁属性对象:pthread_mutexattr_destroy()

  1.函数功能可用来取消分配用于维护pthread_mutexattr_init()所创建的属性对象的存储空间。

项目 说明
函数原型 extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr) __THROW __nonnull ((1));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    EINVAL:由mattr指定的值无效。

初始化互斥锁:pthread_mutex_init()

  1.函数功能:可使用缺省值初始化由__mutex所指向的互斥锁,还可指定已经使用pthread_mutexattr_init()设置的互斥锁属性。__mutexattr的缺省值为NULL

项目 说明
函数原型 extern int pthread_mutex_init (pthread_mutex_t *__mutex, const pthread_mutexattr_t *__mutexattr) __THROW __nonnull ((1));
头文件 pthread.h
参数说明 __mutex:互斥锁
__mutexattr:互斥锁属性
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意 ①初始化互斥锁之前,需将其所在内存清零
②若互斥锁已初始化,则会处于未锁定状态。
③互斥锁可位于进程之间共享的内存中或某个进程的专用内存中。
④__mutexattr设置NULL效果与传递缺省互斥锁属性对象的地址相同,但无内存开销
⑤使用PTHREAD_MUTEX_INITIALIZER宏可以将以静态方式定义的互斥锁初始化为其缺省属性。
⑥当其他线程正在使用某个互斥锁时,请勿重新初始化或销毁该互斥锁。若任一操作没有正确完成,将会导致程序失败。若要重新初始化或销毁某个互斥锁,则应用程序必须确保当前未使用该互斥锁。

  2.错误代码
    EBUSY:该实现已检测到系统尝试重新初始化__mutex所引用的对象,即以前进行过初始化但尚未销毁的互斥锁。
    EINVAL__mutexattr属性值无效。互斥锁尚未修改。
    EFAULT__mutex所指向的互斥锁的地址无效。

使互斥保持一致:pthread_mutex_consistent_np()

  1.函数功能:如果某个互斥锁的属主失败,该互斥锁可能会变为不一致。
    该函数可使互斥对象__mutex在其属主停止之后保持一致。

项目 说明
函数原型 extern int pthread_mutex_consistent_np (pthread_mutex_t *__mutex) __THROW __nonnull ((1));
头文件 pthread.h
参数说明 __mutex:互斥锁
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    ENOSYS:选项_POSIX_ THREAD_PRIO_INHERIT未定义,或者该实现不支持pthread_mutex_consistent_np( )
    EINVAL__mutex属性值无效。

锁定互斥锁:pthread_mutex_lock()

  1.函数功能:可以锁定__mutex所指向的互斥锁。
    当pthread_mutex_lock()返回时,该互斥锁已被锁定。调用线程是该互斥锁的属主。如果该互斥锁已被另一个线程锁定和拥有,则调用线程将阻塞,直到该互斥锁变为可用为止。

项目 说明
函数原型 extern int pthread_mutex_lock (pthread_mutex_t *__mutex) __THROWNL __nonnull ((1));
头文件 pthread.h
参数说明 __mutex:互斥锁
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.注意事项
    1️⃣若互斥锁类型为PTHREAD_MUTEX_NORMAL,则不提供死锁检测。尝试重新锁定互斥锁会导致死锁。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或未锁定,则将产生不确定的行为。
    2️⃣若互斥锁类型为PTHREAD_MUTEX_ERRORCHECK,则会提供错误检查。如果某个线程尝试重新锁定的互斥锁已经由该线程锁定,则将返回错误。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或者未锁定,则将返回错误。
    3️⃣若互斥锁类型为PTHREAD_MUTEX_RECURSIVE,则该互斥锁会保留锁定计数这一概念。线程首次成功获取互斥锁时,锁定计数会设置为1。线程每重新锁定该互斥锁一次,锁定计数就增加1。线程每解除锁定该互斥锁一次,锁定计数就减小1。锁定计数达到0时,该互斥锁即可供其他线程获取。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或者未锁定,则将返回错误。
    4️⃣若互斥锁类型是PTHREAD_MUTEX_DEFAULT,则尝试以递归方式锁定该互斥锁将产生不确定的行为。对于不是由调用线程锁定的互斥锁,如果尝试解除对它的锁定,则会产生不确定的行为。如果尝试解除锁定尚未锁定的互斥锁,则会产生不确定的行为。
  3.错误代码
    EAGAIN:由于已超出了互斥锁递归锁定的最大次数,因此无法获取该互斥锁。
    EDEADLK:当前线程已经拥有互斥锁。

解除锁定互斥锁 :pthread_mutex_unlock()

  1.函数功能:可解除锁定__mutex所指向的互斥锁,释放__mutex引用的互斥锁对象。
    互斥锁的释放方式取决于互斥锁的类型属性。
    若调用pthread_mutex_unlock()时有多个线程被__mutex对象阻塞,则互斥锁变为可用时调度策略可确定获取该互斥锁的线程。对于PTHREAD_MUTEX_RECURSIVE类型的互斥锁,当计数达到零并且调用线程不再对该互斥锁进行任何锁定时,该互斥锁将变为可用。

项目 说明
函数原型 extern int pthread_mutex_unlock (pthread_mutex_t *__mutex) __THROWNL __nonnull ((1));
头文件 pthread.h
参数说明 __mutex:互斥锁
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    EPERM:当前线程不拥有互斥锁。

使用非阻塞互斥锁锁定:pthread_mutex_trylock()

  1.函数功能:可尝试锁定__mutex所指向的互斥锁。
    pthread_mutex_trylock()pthread_mutex_lock()的非阻塞版本。如果__mutex所引用的互斥对象当前被任何线程(包括当前线程)锁定,则将立即返回该调用。否则,该互斥锁将处于锁定状态,调用线程是其属主。

项目 说明
函数原型 extern int pthread_mutex_trylock (pthread_mutex_t *__mutex) __THROWNL __nonnull ((1));
头文件 pthread.h
参数说明 __mutex:互斥锁
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    EBUSY:由于__mutex所指向的互斥锁已锁定,因此无法获取该互斥锁。
    EAGAIN:由于已超出了__mutex的递归锁定最大次数,因此无法获取该互斥锁。

销毁互斥锁:pthread_mutex_destroy()

  1.函数功能:可销毁与__mutex所指向的互斥锁相关联的任何状态。

项目 说明
函数原型 extern int pthread_mutex_destroy (pthread_mutex_t *__mutex) __THROW __nonnull ((1));
头文件 pthread.h
参数说明 __mutex:互斥锁
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    EINVAL__mutex指定的值不会引用已初始化的互斥锁对象。







设置互斥锁的范围:pthread_mutexattr_setpshared()

  1.函数功能:可用来设置互斥锁变量的作用域,通过设置互斥锁属性ATTR的进程共享标志。

项目 说明
函数原型 extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr, int __pshared) __THROW __nonnull ((1));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
__pshared:共享标志
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.共享标志
    PTHREAD_PROCESS_SHARED:若在共享内存中创建互斥锁,设置该标记,可实现在多个进程中的线程之间共享互斥锁。
    PTHREAD_PROCESS_PRIVATE:则仅有那些由同一个进程创建的线程才能够处理该互斥锁。
  3.错误代码
    EINVAL:由mattr指定的值无效。

获取互斥锁的范围:pthread_mutexattr_getpshared()

  1.函数功能:可用来返回由pthread_mutexattr_setpshared()定义的互斥锁变量的范围,即获取互斥锁属性ATTR的进程共享标志。

项目 说明
函数原型 extern int pthread_mutexattr_getpshared (const pthread_mutexattr_t * __restrict __attr, int *__restrict __pshared) __THROW __nonnull ((1, 2));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
__pshared:共享标志
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    EINVAL:由mattr指定的值无效。

设置互斥锁类型的属性:pthread_mutexattr_settype()

  1.函数功能:可用来设置互斥锁的type属性。

项目 说明
函数原型 extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind) __THROW __nonnull ((1));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
__kind:互斥锁类型
默认为PTHREAD_MUTEX_DEFAULT
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.互斥锁类型
  1️⃣PTHREAD_MUTEX_NORMAL
    此类型的互斥锁不会检测死锁。如果线程在不首先解除互斥锁的情况下尝试重新锁定该互斥锁,则会产生死锁。尝试解除由其他线程锁定的互斥锁会产生不确定的行为。如果尝试解除锁定的互斥锁未锁定,则会产生不确定的行为。
  2️⃣PTHREAD_MUTEX_ERRORCHECK
    此类型的互斥锁可提供错误检查。如果线程在不首先解除锁定互斥锁的情况下尝试重新锁定该互斥锁,则会返回错误。如果线程尝试解除锁定的互斥锁已经由其他线程锁定,则会返回错误。如果线程尝试解除锁定的互斥锁未锁定,则会返回错误。
  3️⃣PTHREAD_MUTEX_RECURSIVE
    如果线程在不首先解除锁定互斥锁的情况下尝试重新锁定该互斥锁,则可成功锁定该互斥锁。与PTHREAD_MUTEX_NORMAL类型的互斥锁不同,对此类型互斥锁进行重新锁定时不会产生死锁情况。多次锁定互斥锁需要进行相同次数的解除锁定才可以释放该锁,然后其他线程才能获取该互斥锁。如果线程尝试解除锁定的互斥锁已经由其他线程锁定,则会返回错误。如果线程尝试解除锁定的互斥锁未锁定,则会返回错误。
  4️⃣PTHREAD_MUTEX_DEFAULT
    如果尝试以递归方式锁定此类型的互斥锁,则会产生不确定的行为。对于不是由调用线程锁定的此类型互斥锁,如果尝试对它解除锁定,则会产生不确定的行为。对于尚未锁定的此类型互斥锁,如果尝试对它解除锁定,也会产生不确定的行为。允许在实现中将该互斥锁映射到其他互斥锁类型之一。
  3.错误代码
    EINVAL:由__attr指定的值无效 或 __kind的值无效。

获取互斥锁的类型属性:pthread_mutexattr_gettype()

  1.函数功能:可用来获取由pthread_mutexattr_settype()设置的互斥锁的__kind属性。

项目 说明
函数原型 extern int pthread_mutexattr_gettype (const pthread_mutexattr_t *__restrict __attr, int *__restrict __kind) __THROW __nonnull ((1, 2));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
__kind:互斥锁类型变量地址
返回值 成功返回0,失败返回非零
注意
设置互斥锁属性的协议:pthread_mutexattr_setprotocol()

  1.函数功能:可用来设置互斥锁属性对象的协议属性。

项目 说明
函数原型 extern int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr, int __protocol) __THROW __nonnull ((1));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
__protocol:互斥锁属性协议类型
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.互斥锁属性协议类型
  1️⃣PTHREAD_PRIO_NONE
    线程的优先级和调度不会受到互斥锁拥有权的影响。
  2️⃣PTHREAD_PRIO_INHERIT
    此协议值(如thrd1)会影响线程的优先级和调度。如果更高优先级的线程因thrd1所拥有的一个或多个互斥锁而被阻塞,而这些互斥锁是用PTHREAD_PRIO_INHERIT初始化的,则thrd1将以高于它的优先级或者所有正在等待这些互斥锁(这些互斥锁是thrd1指所拥有的互斥锁)的线程的最高优先级运行。
    如果thrd1因另一个线程(thrd3)拥有的互斥锁而被阻塞,则相同的优先级继承效应会以递归方式传播给thrd3
    使用PTHREAD_PRIO_INHERIT可以避免优先级倒置。低优先级的线程持有较高优先级线程所需的锁时,便会发生优先级倒置。只有在较低优先级的线程释放该锁之后,较高优先级的线程才能继续使用该锁。设置PTHREAD_PRIO_INHERIT,以便按与预期的优先级相反的优先级处理每个线程。
    如果为使用协议属性值PTHREAD_PRIO_INHERIT初始化的互斥锁定义了_POSIX_THREAD_PRIO_INHERIT,则互斥锁的属主失败时会执行以下操作。属主失败时的行为取决于pthread_mutexattr_setrobust_np()robustness参数的值。
      ①解除锁定互斥锁。
      ②互斥锁的下一个属主将获取该互斥锁,并返回错误EOWNERDEAD
      ③互斥锁的下一个属主会尝试使该互斥锁所保护的状态一致。如果上一个属主失败,则状态可能会不一致。如果属主成功使状态保持一致,则可针对该互斥锁调用pthread_mutex_init( )并解除锁定该互斥锁。
      -如果针对以前初始化的但尚未销毁的互斥锁调用pthread_mutex_init(),则该互斥锁不会重新初始化。
      ④如果属主无法使状态保持一致,请勿调用pthread_mutex_init(),而是解除锁定该互斥锁。在这种情况下,所有等待的线程都将被唤醒。以后对pthread_mutex_lock()的所有调用将无法获取互斥锁,并将返回错误代码ENOTRECOVERABLE。现在,通过调用pthread_mutex_destroy()来取消初始化该互斥锁,即可使其状态保持一致。调用pthread_mutex_init()可重新初始化互斥锁。
      ⑤如果已获取该锁的线程失败并返回EOWNERDEAD,则下一个属主将获取该锁及错误代码EOWNERDEAD

  3️⃣PTHREAD_PRIO_PROTECT
    当线程拥有一个或多个使用PTHREAD_PRIO_PROTECT初始化的互斥锁时,此协议值会影响其他线程(如thrd2)的优先级和调度。thrd2以其较高的优先级或者以thrd2拥有的所有互斥锁的最高优先级上限运行。基于被thrd2拥有的任一互斥锁阻塞的较高优先级线程对于thrd2的调度没有任何影响。
  如果某个线程调用sched_setparam()来更改初始优先级,则调度程序不会采用新优先级将该线程移到调度队列末尾。
    线程拥有使用PTHREAD_PRIO_INHERITPTHREAD_PRIO_PROTECT初始化的互斥锁
    线程解除锁定使用PTHREAD_PRIO_INHERITPTHREAD_PRIO_PROTECT初始化的互斥锁
  一个线程可以同时拥有多个混合使用PTHREAD_PRIO_INHERITPTHREAD_PRIO_PROTECT初始化的互斥锁。在这种情况下,该线程将以通过其中任一协议获取的最高优先级执行。
  3.错误代码
    ENOSYS:选项_POSIX_ THREAD_PRIO_INHERIT_POSIX_THREAD_PRIO_PROTECT均未定义并且该实现不支持此函数。
    ENOTSUPprotocol指定的值不受支持。如果出现以下任一情况,pthread_mutexattr_setprotocol()可能会失败并返回对应的值。
    EINVALattrprotocol指定的值无效。
    EPERM:调用方无权执行该操作。

获取互斥锁属性的协议 :pthread_mutexattr_getprotocol()

  1.函数功能:可用来获取互斥锁属性对象的协议属性。

项目 说明
函数原型 extern int pthread_mutexattr_getprotocol (const pthread_mutexattr_t * __restrict __attr, int *__restrict __protocol) __THROW __nonnull ((1, 2));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
__protocol:
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  3.错误代码
    ENOSYS_POSIX_THREAD_PRIO_INHERIT选项和_POSIX_THREAD_PRIO_PROTECT选项均未定义并且该实现不支持此函数。
    如果出现以下任一情况,pthread_mutexattr_getprotocol()可能会失败并返回对应的值。
    EINVALattr指定的值无效。
    EPERM:调用方无权执行该操作。

设置互斥锁属性的优先级上限:pthread_mutexattr_setprioceiling()

  1.函数功能:可用来设置互斥锁属性对象的优先级上限属性,即将*ATTR中的互斥锁prioceiling属性设置为prioceiling

项目 说明
函数原型 extern int pthread_mutexattr_setprioceiling (pthread_mutexattr_t *__attr, int __prioceiling) __THROW __nonnull ((1));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
__prioceiling:指定已初始化互斥锁的优先级上限
优先级上限定义执行互斥锁保护的临界段时的最低优先级。prioceiling位于SCHED_FIFO所定义的优先级的最大范围内。要避免优先级倒置,请将prioceiling设置为高于或等于可能会锁定特定互斥锁的所有线程的最高优先级。
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    ENOSYS:选项_POSIX_THREAD_PRIO_PROTECT未定义并且该实现不支持此函数。
如果出现以下任一情况,pthread_mutexattr_setprioceiling()可能会失败并返回对应的值。
    EINVALattrprioceiling指定的值无效。
    EPERM:调用方无权执行该操作。

获取互斥锁属性的优先级上限 :pthread_mutexattr_getprioceiling()

  1.函数功能:可用来获取互斥锁属性对象的优先级上限属性。

项目 说明
函数原型 extern int pthread_mutexattr_getprioceiling (const pthread_mutexattr_t * __restrict __attr, int *__restrict __prioceiling) __THROW __nonnull ((1, 2));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
__prioceiling:
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    ENOSYS_POSIX_THREAD_PRIO_PROTECT选项未定义并且该实现不支持此函数。
如果出现以下任一情况,pthread_mutexattr_getprioceiling()可能会失败并返回对应的值。
    EINVALattr指定的值无效。
    EPERM:调用方无权执行该操作。

设置互斥锁的强健属性:pthread_mutexattr_setrobust_np()

  1.函数功能:可用来设置互斥锁属性对象的强健属性。

项目 说明
函数原型 extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr, int __robustness) __THROW __nonnull ((1));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
__robustness:互斥锁属性对象的强健属性值
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    ENOSYS:选项_POSIX_ THREAD_PRIO__INHERIT未定义,或者该实现不支持pthread_mutexattr_setrobust_np()
    ENOTSUProbustness指定的值不受支持。
    EINVALattrrobustness指定的值无效。

获取互斥锁的强健属性:pthread_mutexattr_getrobust_np()

  1.函数功能:可用来获取互斥锁属性对象的强健属性。

项目 说明
函数原型 extern int pthread_mutexattr_getrobust_np (const pthread_mutexattr_t *__attr, int *__robustness) __THROW __nonnull ((1, 2));
头文件 pthread.h
参数说明 __attr:属性对象
pthread_mutexattr_t类型变量地址
__robustness:互斥锁属性对象的强健属性值
返回值 成功返回0,失败返回非零,并设置errno以指示错误状态。
注意

  2.错误代码
    ENOSYS:选项_POSIX_THREAD_PRIO__INHERIT未定义,或者该实现不支持pthread_mutexattr_getrobust_np()
    EINVAL: attr或robustness指定的值无效。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值