(转载)pThreads线程(二) 线程同步--互斥量/锁

本文详细介绍了pThreads中线程同步的重要概念——互斥量(Mutex),包括其创建、初始化、锁定及解锁的方法,并通过实例展示了如何使用互斥量保护共享数据,防止多个线程同时写入导致的数据不一致问题。

  互斥量(Mutex)是“mutual exclusion”的缩写。互斥量是实现线程同步,和保护同时写共享数据的主要方法。
  互斥量对共享数据的保护就像一把锁。在Pthreads中,任何时候仅有一个线程可以锁定互斥量,因此,当多个线程尝试去锁定该互斥量时仅有一个会成功。直到锁定互斥量的线程解锁互斥量后,其他线程才可以去锁定互斥量。线程必须轮着访问受保护数据。
  一个拥有互斥量的线程经常用于更新全局变量。确保了多个线程更新同样的变量以安全的方式运行,最终的结果和一个线程处理的结果是相同的。这个更新的变量属于一个“临界区(critical section)”。


  使用互斥量的典型顺序如下:

  • 创建和初始一个互斥量
  • 多个线程尝试去锁定该互斥量
  • 仅有一个线程可以成功锁定改互斥量
  • 锁定成功的线程做一些处理
  • 线程解锁该互斥量
  • 另外一个线程获得互斥量,重复上述过程
  • 最后销毁互斥量

  当多个线程竞争同一个互斥量时,失败的线程会阻塞在lock调用处。可以用“trylock”替换“lock”,则失败时不会阻塞。当保护共享数据时,程序员有责任去确认是否需要使用互斥量。如,若四个线程会更新同样的数据,但仅有一个线程用了互斥量,则数据可能会损坏。

 

 

创建和销毁互斥量:
pthread_mutex_init (mutex,attr)  
pthread_mutex_destroy (mutex)  
pthread_mutexattr_init (attr)  
pthread_mutexattr_destroy (attr) 

用法

互斥量必须用类型pthread_mutex_t类型声明,在使用前必须初始化,这里有两种方法可以初始化互斥量:
声明时静态地,如: pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
动态地用pthread_mutex_init()函数,这种方法允许设定互斥量的属性对象attr。
互斥量初始化后是解锁的。
attr对象用于设置互斥量对象的属性,使用时必须声明为pthread_mutext_attr_t类型,默认值可以是NULL。Pthreads标准定义了三种可选的互斥量属性:

  • 协议(Protocol): 指定了协议用于阻止互斥量的优先级改变
  • 优先级上限(Prioceiling):指定互斥量的优先级上限
  • 进程共享(Process-shared):指定进程共享互斥量

注意所有实现都提供了这三个可先的互斥量属性。
pthread_mutexattr_init()和pthread_mutexattr_destroy()函数分别用于创建和销毁互斥量属性对象。
pthread_mutex_destroy()应该用于释放不需要再使用的互斥量对象。

锁定和解锁互斥量:

函数

pthread_mutex_lock (mutex)  
pthread_mutex_trylock (mutex)  
pthread_mutex_unlock (mutex)  

用法

线程用pthread_mutex_lock()函数去锁定指定的mutex变量,若该mutex已经被另外一个线程锁定了,该调用将会阻塞线程直到mutex被解锁。
pthread_mutex_trylock() will attempt to lock a mutex. However, if the mutex is already locked, the routine will return immediately with a "busy" error code. This routine may be useful in pthread_mutex_trylock().

  尝试着去锁定一个互斥量,然而,若互斥量已被锁定,程序会立刻返回并返回一个忙错误值。该函数在优先级改变情况下阻止死锁是非常有用的。线程可以用pthread_mutex_unlock()解锁自己占用的互斥量。在一个线程完成对保护数据的使用,而其它线程要获得互斥量在保护数据上工作时,可以调用该函数。若有一下情形则会发生错误:

  • 互斥量已经被解锁
  • 互斥量被另一个线程占用

互斥量并没有多么“神奇”的,实际上,它们就是参与的线程的“君子约定”。写代码时要确信正确地锁定,解锁互斥量。
Q:有多个线程等待同一个锁定的互斥量,当互斥量被解锁后,那个线程会第一个锁定互斥量?
A:除非线程使用了优先级调度机制,否则,线程会被系统调度器去分配,那个线程会第一个锁定互斥量是随机的。

用例: 

 1 #include<stdlib.h>  
 2 #include<stdio.h>  
 3 #include<unistd.h>  
 4 #include<pthread.h>  
 5 
 6 typedef struct ct_sum  7 {  8 int sum;  9 pthread_mutex_t lock; 10 }ct_sum; 11 12 void * add1(void *cnt) 13 { 14 pthread_mutex_lock(&(((ct_sum*)cnt)->lock)); 15 for(int i=0; i < 50; i++) 16  { 17 (*(ct_sum*)cnt).sum += i; 18  } 19 pthread_mutex_unlock(&(((ct_sum*)cnt)->lock)); 20  pthread_exit(NULL); 21 return 0; 22 } 23 void * add2(void *cnt) 24 { 25 pthread_mutex_lock(&(((ct_sum*)cnt)->lock)); 26 for(int i=50; i<101; i++) 27  { 28 (*(ct_sum*)cnt).sum += i; 29  } 30 pthread_mutex_unlock(&(((ct_sum*)cnt)->lock)); 31  pthread_exit(NULL); 32 return 0; 33 } 34 35 int main(void) 36 { 37  pthread_t ptid1, ptid2; 38  ct_sum cnt; 39 pthread_mutex_init(&(cnt.lock), NULL); 40 cnt.sum=0; 41 42 pthread_create(&ptid1, NULL, add1, &cnt); 43 pthread_create(&ptid2, NULL, add2, &cnt); 44 45  pthread_join(ptid1,NULL); 46  pthread_join(ptid2,NULL); 47 48 printf("sum %d\n", cnt.sum); 49 pthread_mutex_destroy(&(cnt.lock)); 50 51 return 0; 52 } 

 

原文地址:http://www.cnblogs.com/dongsheng/p/4186358.html

转载于:https://www.cnblogs.com/wodehao0808/p/8616777.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值