




已阅读5页,还剩9页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
互斥锁是管理临界资源的一种有效手段。因为互斥锁是独占的,所以在一个时刻只允许一个线程占有互斥锁,利用这个性质来实现共享资源的互斥锁保护。任何时刻只允许一个线程获得互斥量对象,未能够获得互斥量对象的线程被挂起在该互斥量的等待线程队列上。1 互斥锁控制块cpp view plaincopyprint?1. /*2. *Mutualexclusion(mutex)structure3. */4. structrt_mutex5. 6. structrt_ipc_objectparent;/*inheritfromipc_object*/派生自IPC对象7. 8. rt_uint16_tvalue;/*valueofmutex*/此互斥锁的值9. 10. rt_uint8_toriginal_priority;/*priorityoflastthreadholdthemutex*/原始优先级,即此互斥锁拥有者线程的优先级11. rt_uint8_thold;/*numbersofthreadholdthemutex*/此互斥锁当前已被几个线程(同一线程)take的次数12. 13. structrt_thread*owner;/*currentownerofmutex*/此互斥锁的拥有者线程14. ;15. typedefstructrt_mutex*rt_mutex_t;/* * Mutual exclusion (mutex) structure */struct rt_mutex struct rt_ipc_object parent; /* inherit from ipc_object */派生自IPC对象 rt_uint16_t value; /* value of mutex */此互斥锁的值 rt_uint8_t original_priority; /* priority of last thread hold the mutex */原始优先级,即此互斥锁拥有者线程的优先级 rt_uint8_t hold; /* numbers of thread hold the mutex */此互斥锁当前已被几个线程(同一线程)take的次数 struct rt_thread *owner; /*parent.parent),RT_Object_Class_Mutex,name);/初始化互斥锁的内核对象 17. 18. /*initipcobject*/19. rt_ipc_object_init(&(mutex-parent);/初始化互斥锁的IPC对象 20. 21. mutex-value=1;/设置互斥锁值初始化为1 22. mutex-owner=RT_NULL;/初始化互斥锁当前没有拥有者 23. mutex-original_priority=0xFF;/初始化互斥锁原始优先级为255,即拥有者线程的优先级 24. mutex-hold=0;/初化为当前互斥锁的被take的次数为0(同一线程) 25. 26. /*setflag*/27. mutex-parent.parent.flag=flag;/设置互斥锁的内核对象标志 28. 29. returnRT_EOK;30. /* * This function will initialize a mutex and put it under control of resource * management. * * param mutex the mutex object * param name the name of mutex * param flag the flag of mutex * * return the operation status, RT_EOK on successful */rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag) RT_ASSERT(mutex != RT_NULL); /* init object */ rt_object_init(&(mutex-parent.parent), RT_Object_Class_Mutex, name);/初始化互斥锁的内核对象 /* init ipc object */ rt_ipc_object_init(&(mutex-parent);/初始化互斥锁的IPC对象 mutex-value = 1;/设置互斥锁值初始化为1 mutex-owner = RT_NULL;/初始化互斥锁当前没有拥有者 mutex-original_priority = 0xFF;/初始化互斥锁原始优先级为255,即拥有者线程的优先级 mutex-hold = 0;/初化为当前互斥锁的被take的次数为0(同一线程) /* set flag */ mutex-parent.parent.flag = flag;/设置互斥锁的内核对象标志 return RT_EOK;注意互斥锁在初始化时其值value被初始化为1,即默认情况下其是可用的.在其被take之后value值减1变为0时才不可用.2.2 创建互斥锁cpp view plaincopyprint?1. /*2. *Thisfunctionwillcreateamutexfromsystemresource3. *4. *paramnamethenameofmutex5. *paramflagtheflagofmutex6. *7. *returnthecreatedmutex,RT_NULLonerrorhappen8. *9. *seert_mutex_init10. */11. rt_mutex_trt_mutex_create(constchar*name,rt_uint8_tflag)12. 13. structrt_mutex*mutex;14. 15. RT_DEBUG_NOT_IN_INTERRUPT;/确保此函数不是在ISR中使用 16. 17. /*allocateobject*/18. mutex=(rt_mutex_t)rt_object_allocate(RT_Object_Class_Mutex,name);/动态分配一个互斥锁 19. if(mutex=RT_NULL)20. returnmutex;21. 22. /*initipcobject*/23. rt_ipc_object_init(&(mutex-parent);/初始化此互斥锁的内核IPC对象 24. 25. mutex-value=1;/初始化互斥锁的值为1 26. mutex-owner=RT_NULL;/无拥有者 27. mutex-original_priority=0xFF;/互斥锁原始优先级为255 28. mutex-hold=0;/take此互斥锁的线程个数(同一线程)次数为0 29. 30. /*setflag*/31. mutex-parent.parent.flag=flag;/设置互斥锁内核对象标志 32. 33. returnmutex;34. /* * This function will create a mutex from system resource * * param name the name of mutex * param flag the flag of mutex * * return the created mutex, RT_NULL on error happen * * see rt_mutex_init */rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag) struct rt_mutex *mutex; RT_DEBUG_NOT_IN_INTERRUPT;/确保此函数不是在ISR中使用 /* allocate object */ mutex = (rt_mutex_t)rt_object_allocate(RT_Object_Class_Mutex, name);/动态分配一个互斥锁 if (mutex = RT_NULL) return mutex; /* init ipc object */ rt_ipc_object_init(&(mutex-parent);/初始化此互斥锁的内核IPC对象 mutex-value = 1;/初始化互斥锁的值为1 mutex-owner = RT_NULL;/无拥有者 mutex-original_priority = 0xFF;/互斥锁原始优先级为255 mutex-hold = 0;/take此互斥锁的线程个数(同一线程)次数为0 /* set flag */ mutex-parent.parent.flag = flag;/设置互斥锁内核对象标志 return mutex;此函数与初始化类似,直接跳过.3 脱离或删除互斥锁3.1 脱离互斥锁cpp view plaincopyprint?1. /*2. *Thisfunctionwilldetachamutexfromresourcemanagement3. *4. *parammutexthemutexobject5. *6. *returntheoperationstatus,RT_EOKonsuccessful7. *8. *seert_mutex_delete9. */10. rt_err_trt_mutex_detach(rt_mutex_tmutex)11. 12. RT_ASSERT(mutex!=RT_NULL);13. 14. /*wakeupallsuspendthreads*/15. rt_ipc_list_resume_all(&(mutex-parent.suspend_thread);/唤醒所有挂起的线程 16. 17. /*detachsemaphoreobject*/18. rt_object_detach(&(mutex-parent.parent);/脱离互斥锁的内核对象 19. 20. returnRT_EOK;21. /* * This function will detach a mutex from resource management * * param mutex the mutex object * * return the operation status, RT_EOK on successful * * see rt_mutex_delete */rt_err_t rt_mutex_detach(rt_mutex_t mutex) RT_ASSERT(mutex != RT_NULL); /* wakeup all suspend threads */ rt_ipc_list_resume_all(&(mutex-parent.suspend_thread);/唤醒所有挂起的线程 /* detach semaphore object */ rt_object_detach(&(mutex-parent.parent);/脱离互斥锁的内核对象 return RT_EOK;脱离互斥锁只要是唤醒挂起的线程及脱离其内核对象,没有什么好说明的.3.2 删除互斥锁cpp view plaincopyprint?1. /*2. *Thisfunctionwilldeleteamutexobjectandreleasethememory3. *4. *parammutexthemutexobject5. *6. *returntheerrorcode7. *8. *seert_mutex_detach9. */10. rt_err_trt_mutex_delete(rt_mutex_tmutex)11. 12. RT_DEBUG_NOT_IN_INTERRUPT;/确保此函数不是在ISR中使用 13. 14. RT_ASSERT(mutex!=RT_NULL);15. 16. /*wakeupallsuspendthreads*/17. rt_ipc_list_resume_all(&(mutex-parent.suspend_thread);/唤醒所有挂起的线程 18. 19. /*deletesemaphoreobject*/20. rt_object_delete(&(mutex-parent.parent);/删除互斥锁的内核对象 21. 22. returnRT_EOK;23. /* * This function will delete a mutex object and release the memory * * param mutex the mutex object * * return the error code * * see rt_mutex_detach */rt_err_t rt_mutex_delete(rt_mutex_t mutex) RT_DEBUG_NOT_IN_INTERRUPT;/确保此函数不是在ISR中使用 RT_ASSERT(mutex != RT_NULL); /* wakeup all suspend threads */ rt_ipc_list_resume_all(&(mutex-parent.suspend_thread);/唤醒所有挂起的线程 /* delete semaphore object */ rt_object_delete(&(mutex-parent.parent);/删除互斥锁的内核对象 return RT_EOK;除了唤醒挂起的线程还需要删除其内核对象.3.3 获取互斥锁cpp view plaincopyprint?1. /*2. *Thisfunctionwilltakeamutex,ifthemutexisunavailable,the3. *threadshallwaitforaspecifiedtime.4. *5. *parammutexthemutexobject6. *paramtimethewaitingtime7. *8. *returntheerrorcode9. */10. rt_err_trt_mutex_take(rt_mutex_tmutex,rt_int32_ttime)11. 12. registerrt_base_ttemp;13. structrt_thread*thread;14. 15. /*thisfunctionmustnotbeusedininterrupteveniftime=0*/16. RT_DEBUG_NOT_IN_INTERRUPT;/确保此函数不是在ISR中使用 17. 18. RT_ASSERT(mutex!=RT_NULL);19. 20. /*disableinterrupt*/21. temp=rt_hw_interrupt_disable();/关中断 22. 23. /*getcurrentthread*/24. thread=rt_thread_self();/获取当前线程 25. 26. RT_OBJECT_HOOK_CALL(rt_object_trytake_hook,(&(mutex-parent.parent);27. 28. RT_DEBUG_LOG(RT_DEBUG_IPC,29. (mutex_take:currentthread%s,mutexvalue:%d,hold:%dn,30. thread-name,mutex-value,mutex-hold);31. 32. /*resetthreaderror*/33. thread-error=RT_EOK;/设置当前线程的错误标志为RT_EOK 34. 35. if(mutex-owner=thread)/如果当前互斥锁的拥有者就是当前线程,即当前线程重复take同一互斥锁,则当前互斥锁的take次数加1 36. 37. /*itsthesamethread*/38. mutex-hold+;39. 40. else/如果当前互斥锁的拥有者不是本身线程 41. 42. /*Thevalueofmutexis1ininitialstatus.Therefore,ifthe43. *valueisgreatthan0,itindicatesthemutexisavaible.44. */45. if(mutex-value0)/当前互斥锁的值大于0,则说明此互斥锁可用 46. 47. /*mutexisavailable*/48. mutex-value-;/将互斥锁的值减1 49. 50. /*setmutexownerandoriginalpriority*/51. mutex-owner=thread;/设置互斥锁的拥有者为当前线程 52. mutex-original_priority=thread-current_priority;/设置互斥锁的原始优先级为当前线程的优先级 53. mutex-hold+;/互斥锁被成功take,take次数加1 54. 55. else/如果当前互斥锁不可用 56. 57. /*nowaiting,returnwithtimeout*/58. if(time=0)/如果等待参数为0,则应立即返回错误 59. 60. /*seterrorastimeout*/61. thread-error=-RT_ETIMEOUT;/设置超时错误 62. 63. /*enableinterrupt*/64. rt_hw_interrupt_enable(temp);/开中断 65. 66. return-RT_ETIMEOUT;/返回超时错误 67. 68. else/如果时间参数不为0 69. 70. /*mutexisunavailable,pushtosuspendlist*/71. RT_DEBUG_LOG(RT_DEBUG_IPC,(mutex_take:suspendthread:%sn,72. thread-name);73. 74. /*changetheownerthreadpriorityofmutex*/75. if(thread-current_priorityowner-current_priority)/如果当前线程的优先级比互斥锁拥有者线程大的话(优先级值越小,优先级越高) 76. 77. /*changetheownerthreadpriority*/78. rt_thread_control(mutex-owner,/则修改当前互斥锁拥有者线程的优先级降为当前线程的优先级,如果不这么做的话,则如果拥有者线程永远不释放,则当前线程永远不可能获取此互斥锁,这样有可以会造成问题 79. RT_THREAD_CTRL_CHANGE_PRIORITY,/这样拥有者线程和当前线程优先级相同,系统采用时间片轮转方式,当前线程就有了获得互斥锁的可能了 80. &thread-current_priority);81. 82. 83. /*suspendcurrentthread*/84. rt_ipc_list_suspend(&(mutex-parent.suspend_thread),/挂起当前线程 85. thread,86. mutex-parent.parent.flag);87. 88. /*haswaitingtime,startthreadtimer*/89. if(time0)/如果时间参数大于0 90. 91. RT_DEBUG_LOG(RT_DEBUG_IPC,92. (mutex_take:startthetimerofthread:%sn,93. thread-name);94. 95. /*resetthetimeoutofthreadtimerandstartit*/96. rt_timer_control(&(thread-thread_timer),/设置定时器 97. RT_TIMER_CTRL_SET_TIME,98. &time);99. rt_timer_start(&(thread-thread_timer);/启动定时器 100. 101. 102. /*enableinterrupt*/103. rt_hw_interrupt_enable(temp);/开中断 104. 105. /*doschedule*/106. rt_schedule();/立即重新调度线程 107. 108. if(thread-error!=RT_EOK)/等待时间已到,但还是未成功获得互斥锁时,thread-error的值会被设为-RT_ETIMEOUT,见thread.c源文件中的rt_thread_timeout函数 109. 110. /*returnerror*/111. returnthread-error;112. 113. else/如果在另一线程执行rt_mutex_release函数唤醒此线程,则此线程在在处被唤醒时即已经获得互斥锁,这一过程中thread-error的值都未被修改,还是保持为RT_EOK 114. 115. /*themutexistakensuccessfully.*/116. /*disableinterrupt*/117. temp=rt_hw_interrupt_disable();/关中断 118. 119. 120. 121. 122. 123. /*enableinterrupt*/124. rt_hw_interrupt_enable(temp);/开中断 125. 126. RT_OBJECT_HOOK_CALL(rt_object_take_hook,(&(mutex-parent.parent);127. 128. returnRT_EOK;129. /* * This function will take a mutex, if the mutex is unavailable, the * thread shall wait for a specified time. * * param mutex the mutex object * param time the waiting time * * return the error code */rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time) register rt_base_t temp; struct rt_thread *thread; /* this function must not be used in interrupt even if time = 0 */ RT_DEBUG_NOT_IN_INTERRUPT;/确保此函数不是在ISR中使用 RT_ASSERT(mutex != RT_NULL); /* disable interrupt */ temp = rt_hw_interrupt_disable();/关中断 /* get current thread */ thread = rt_thread_self();/获取当前线程 RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mutex-parent.parent); RT_DEBUG_LOG(RT_DEBUG_IPC, (mutex_take: current thread %s, mutex value: %d, hold: %dn, thread-name, mutex-value, mutex-hold); /* reset thread error */ thread-error = RT_EOK;/设置当前线程的错误标志为RT_EOK if (mutex-owner = thread)/如果当前互斥锁的拥有者就是当前线程,即当前线程重复take同一互斥锁,则当前互斥锁的take次数加1 /* its the same thread */ mutex-hold +; else/如果当前互斥锁的拥有者不是本身线程 /* The value of mutex is 1 in initial status. Therefore, if the * value is great than 0, it indicates the mutex is avaible. */ if (mutex-value 0)/当前互斥锁的值大于0,则说明此互斥锁可用 /* mutex is available */ mutex-value -;/将互斥锁的值减1 /* set mutex owner and original priority */ mutex-owner = thread;/设置互斥锁的拥有者为当前线程 mutex-original_priority = thread-current_priority;/设置互斥锁的原始优先级为当前线程的优先级 mutex-hold +;/互斥锁被成功take,take次数加1 else/如果当前互斥锁不可用 /* no waiting, return with timeout */ if (time = 0)/如果等待参数为0,则应立即返回错误 /* set error as timeout */ thread-error = -RT_ETIMEOUT;/设置超时错误 /* enable interrupt */ rt_hw_interrupt_enable(temp);/开中断 return -RT_ETIMEOUT;/返回超时错误 else/如果时间参数不为0 /* mutex is unavailable, push to suspend list */ RT_DEBUG_LOG(RT_DEBUG_IPC, (mutex_take: suspend thread: %sn, thread-name); /* change the owner thread priority of mutex */ if (thread-current_priority owner-current_priority)/如果当前线程的优先级比互斥锁拥有者线程大的话(优先级值越小,优先级越高) /* change the owner thread priority */ rt_thread_control(mutex-owner,/则修改当前互斥锁拥有者线程的优先级降为当前线程的优先级,如果不这么做的话,则如果拥有者线程永远不释放,则当前线程永远不可能获取此互斥锁,这样有可以会造成问题 RT_THREAD_CTRL_CHANGE_PRIORITY,/这样拥有者线程和当前线程优先级相同,系统采用时间片轮转方式,当前线程就有了获得互斥锁的可能了 &thread-current_priority); /* suspend current thread */ rt_ipc_list_suspend(&(mutex-parent.suspend_thread),/挂起当前线程 thread, mutex-parent.parent.flag); /* has waiting time, start thread timer */ if (time 0)/如果时间参数大于0 RT_DEBUG_LOG(RT_DEBUG_IPC, (mutex_take: start the timer of thread:%sn, thread-name); /* reset the timeout of thread timer and start it */ rt_timer_control(&(thread-thread_timer),/设置定时器 RT_TIMER_CTRL_SET_TIME, &time); rt_timer_start(&(thread-thread_timer);/启动定时器 /* enable interrupt */ rt_hw_interrupt_enable(temp);/开中断 /* do schedule
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 甲状腺癌术后护理课件
- 甲状腺功能的调节
- 18 牛和鹅教学课件
- 新解读《GB-T 36788-2018病媒生物密度监测方法 蜱类》
- 用谷歌地球做课件
- 用电安全知识培训课件通知
- Unit6 Celebrating the Big Days单元测试卷(含答案) 仁爱科普版(2024)七年级英语上册
- 用电安全知识培训大纲课件
- 生铁废钢基础知识培训课件
- 生理解剖兔子实验课件
- 商城搭建方案
- 胰腺炎(修订版)
- 苏州团餐行业分析
- 食管癌化疗病人护理查房课件
- 第三章:堤防工程加固施工
- 胰岛素抵抗介绍演示培训课件
- 蒂森CTU2调试说明附件
- GB/T 21837-2023铁磁性钢丝绳电磁检测方法
- 血液透析对常用降压药物的清除作用及治疗后补充
- QC新老七大工具培训课件
- 中铝矿业有限公司巩义市张家沟大发铝土矿矿山土地复垦与地质环境保护治理方案
评论
0/150
提交评论