c – 线程互斥行为
我正在学习C.我正在编写一个包含多个线程的应用程序;我知道当一个变量在两个或多个线程之间共享时,最好使用互斥锁来锁定/解锁,以避免死锁和变量的不一致.当我想要更改或查看一个变量时,这一点非常清楚.
int i = 0; /** Global */ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /** Thread 1. */ pthread_mutex_lock(&mutex); i++; pthread_mutex_unlock(&mutex); /** Thread 2. */ pthread_mutex_lock(&mutex); i++; pthread_mutex_unlock(&mutex); 我认为这是正确的.变量i在执行结束时包含整数2. 例如,假设您有一个函数obtain(),它返回一个全局变量.我需要从两个线程中调用该函数.我还有另外两个调用函数set()的线程,用一些参数定义;此函数将设置相同的全局变量.在获取/设置var之前需要执行某些操作时,这两个函数是必需的. /** (0) */ /** Thread 1,or 2,or 3... */ if(obtain() == something) { if(obtain() == somethingElse) { // Do this,sometimes obtain() and sometimes set(random number) (1) } else { // Do that,just obtain(). (2) } } else { // Do this and do that (3) // If # of thread * 3 > 10,then set(3*10) For example. (4) } /** (5) */ 我必须锁定的地方,以及我必须解锁的地方? 先感谢您. 解决方法
没有任何保护:
操作系统可以随时中断每个线程,并将处理器交给另一个. “Anytime”包括“实际来自同一C命令的两个汇编指令之间”. 现在,假设您的变量在32位处理器中占用64位.这意味着您的变量占用了两个处理器“单词”.为了编写它,处理器需要两个汇编指令.同样适合阅读.如果线程在两者之间中断,则会遇到麻烦. 为了给出一个更清晰的例子,我将使用两个十进制数字的类比来表示两个二进制32位字.因此,假设您在1位处理器中递增两位十进制数.要增加19到20,必须读取19,进行数学运算,然后写入20.要编写20,必须写入2然后写入0(反之亦然).如果你写2,然后在写0之前被中断,那么内存中的数字将是29,远远不是实际上正确的数字.然后另一个线程继续读取错误的数字. 即使你有一个数字,仍然有读取 – 修改 – 写问题Blank Xavier解释. 使用互斥锁: 当线程A锁定互斥锁时,线程A会检查互斥锁变量.如果它是空闲的,则线程A将其写为已采用.它使用原子指令,一个汇编指令来完成它,因此没有“介于两者之间”来中断.然后它继续增加19到20.它仍然可以在错误的29变量值期间被中断,但是没关系,因为现在没有其他人可以访问该变量.当线程B试图锁定互斥锁时,它会检查互斥锁变量,然后执行该操作.所以线程B知道它无法触及变量.然后它调用操作系统,说“我现在放弃处理器”.线程B将重复它,如果它再次获得处理器.然后再次.直到线程A最终得到处理器,完成它正在做的事情,然后解锁互斥锁. 那么,何时锁定? 这么多东西,取决于它.主要是关于应用程序需要正常工作的特定行为顺序.您需要在阅读或写作之前始终锁定以获得保护,然后再解锁.但是“锁定的代码块”可能有许多命令,或者只有一个命令.保持上面解释的舞蹈并考虑应用程序应该如何表现. 还存在性能问题.如果您锁定/解锁每一行代码,就会浪费时间锁定/解锁.如果只围绕大量代码锁定/解锁,那么每个线程将等待很长时间让另一个线程释放互斥锁. 不是真的“永远” 现在,在某些情况下您可以跳过锁定解锁.它们发生在处理一位数(意味着一个处理器字)变量时,并且每个线程要么只读取它,要么只写它,所以读取的值不会决定以后写入什么值.只有当您非常确定自己在做什么时才这样做,并且确实需要提高性能. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- oracle 数据重复,只取一条
- 如何在Oracle中跟踪哪些表/视图/ etc取决于表
- CitrusEngine系列教程五:使用PhysicsEditor创建box2d刚体
- FusionCharts或其它flash的div图层总是浮在最上层?
- Creating a Flex Mashup on Force.com
- iphone – 如何在一个命令中更改所有标签字体
- XML note
- 关于XML文档的xmlns、xmlns:xsi和xsi:schemaLocation
- 【unity】利用sqlite制作排行榜
- Flex 4 Gumbo DOM Tree API - Functional and Design Speci