作者: 何养义张章伟
在本文中,我们总结了Linux上多线程编程主要功能的5种经验,以改善Linux多线程编程的习惯并避免开发陷阱. 在本文中,我们将穿插一些Windows编程用例,以比较Linux的功能,以加深读者的印象.
背景
与其他平台(例如Windows)的多线程API相比,Linux平台上的多线程程序开发具有微妙的差异. 不注意Linux上的一些开发陷阱通常会导致无休止的程序问题和持续的死锁. 在本文中,我们从五个方面总结了Linux多线程编程中的问题,并提供了相关的开发经验来避免这些陷阱. 我们希望这种经验能帮助读者更加熟悉Linux平台上的多线程编程.
我们假设读者已经熟悉Linux平台上用于线程编程的基本Pthread库API. 本文不会提及其他用于线程编程的第三方库,例如boost. 本文涵盖的主要主题包括线程管理,互斥变量和线程开发中的条件变量. 流程概念不会在本文中介绍.
Linux上的线程开发API概述
多线程开发在Linux平台上已经具有成熟的Pthread库支持. 多线程开发的最基本概念涉及三点: 线程,互斥量和条件. 其中,线程操作分为线程创建,退出和等待三种类型. 互斥锁包括四个操作,即创建,销毁,锁定和解锁. 有五种类型的条件操作: 创建,销毁,触发,广播和等待. 其他线程扩展概念linux多线程编程面试题,例如信号量,可以通过上面三个基本元素的基本操作来封装.
线程,互斥锁和条件Linux平台上的相应API可以总结在表1中. 为了方便熟悉Windows线程编程的读者熟悉Linux中用于多线程开发的API,我们还列出了相应的API. 表格中Windows SDK库中的API名称.
表1.线程功能列表
对象
动作
Linux Pthread API
Windows SDK库对应的API
线程
创建
pthread_create
CreateThread
退出
pthread_exit
ThreadExit
等待
pthread_join
WaitForSingleObject
互斥锁
创建
pthread_mutex_init
CreateMutex
破坏
pthread_mutex_destroy
CloseHandle
已锁定
pthread_mutex_lock
WaitForSingleObject
解锁
pthread_mutex_unlock
ReleaseMutex
条件
创建
pthread_cond_init
CreateEvent
破坏
pthread_cond_destroy
CloseHandle
触发
pthread_cond_signal
SetEvent
广播
pthread_cond_broadcast
SetEvent / ResetEvent
等待
pthread_cond_wait / pthread_cond_timedwait
SingleObjectAndWait
多线程开发在Linux平台上已经具有成熟的Pthread库支持. 多线程开发的最基本概念涉及三点: 线程,互斥量和条件. 其中,线程操作分为线程创建,退出和等待三种类型. 互斥锁包括四个操作,即创建,销毁,锁定和解锁. 有五种类型的条件操作: 创建,销毁,触发,广播和等待. 其他线程扩展概念,例如信号量,可以通过上面三个基本元素的基本操作来封装.
Linux线程编程中的5课
尝试设置递归属性以初始化Linux的互斥变量
Mutex是多线程编程中的基本概念,并在开发中广泛使用. 调用序列层次结构清晰而简单: 构建锁定,锁定,解锁linux多线程编程面试题,销毁锁定. 但是,应注意,与Windows平台等互斥变量不同,默认情况下,Linux下的同一线程无法递归加速相同的互斥,否则会发生死锁.
所谓的递归锁是尝试在同一线程中执行两个或多个互斥锁. 清单1中显示了Linux平台上该方案的代码.
清单1.反复列出Linux互斥锁实例
// 通过默认条件建锁
pthread_mutex_t *theMutex = new pthread_mutex_t;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutex_init(theMutex,&attr);
pthread_mutexattr_destroy(&attr);
// 递归加锁
pthread_mutex_lock (theMutex);
pthread_mutex_lock (theMutex);
pthread_mutex_unlock (theMutex);
pthread_mutex_unlock (theMutex);
在上述代码方案中,问题将是第二次锁定操作. 由于Linux默认情况下不允许在同一线程上进行递归锁定,因此线程将在第二次锁定操作时死锁.
Linux互斥变量的奇怪行为在某些情况下可能有用,但是在大多数情况下,它看起来更像是程序中的错误. 毕竟,经常需要在同一线程中递归锁定同一互斥锁,尤其是在二次开发中.
此问题与互斥锁中的默认递归属性有关. 解决方案是在初始化互斥锁时显式设置递归属性. 基于此,上面的代码经过一些修改实际上可以正常运行. 您只需要在初始化锁时设置属性. 看清单2.
清单2.设置互斥量递归属性实例
pthread_mutexattr_init(&attr);
// 设置 recursive 属性
pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutex_init(theMutex,&attr);
因此,建议尽可能设置递归属性以初始化Linux互斥锁. 这样可以解决递归锁定同一线程的问题,并在许多情况下避免死锁. 这具有使锁在Windows和Linux下统一运行的额外好处.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-148406-1.html