1# 小凌派-RK2206开发板OpenHarmonyOS内核开发-互斥锁 2 3## 实验内容 4 5本例程演示如何在小凌派-RK2206开发板上使用鸿蒙LiteOS-M内核接口,进行互斥锁编程开发。 6 7![小凌派-RK2206开发板](../../docs/figures/lockzhiner-rk2206.jpg) 8 9## 程序设计 10 11互斥锁也叫做互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理。 12 13在任意时刻互斥锁的状态只有两种,开锁或闭锁。当有任务持有时,互斥锁处于闭锁状态,这个任务获得该互斥锁的所有权。当该任务释放它时,该互斥锁被开锁,任务失去该互斥锁的所有权。当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。 14 15多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问;另外,互斥锁可以解决信号量存在的优先级翻转问题。需要注意的是,互斥锁不能在中断服务程序中使用。 16 17### API分析 18 19#### LOS_MuxCreate() 20 21```c 22UINT32 LOS_MuxCreate(UINT32 *muxHandle); 23``` 24 25**描述:** 26 27创建互斥锁 28 29**参数:** 30 31| 名字 | 描述 | 32| :-------- | :--------------- | 33| muxHandle | 创建的互斥锁指针 | 34 35**返回值:** 36 37| 返回值 | 描述 | 38| :---------------------------------------------------- | :--- | 39| LOS_OK | 成功 | 40| LOS_ERRNO_MUX_PTR_NULL`<br>` LOS_ERRNO_MUX_ALL_BUSY | 失败 | 41 42#### LOS_MuxDelete() 43 44```c 45UINT32 LOS_MuxDelete(UINT32 muxHandle); 46``` 47 48**描述:** 49 50删除指定的互斥锁 51 52**参数:** 53 54| 名字 | 描述 | 55| :-------- | :--------------- | 56| muxHandle | 需要删除的互斥锁 | 57 58**返回值:** 59 60| 返回值 | 描述 | 61| :------------------------------------------------- | :--- | 62| LOS_OK | 成功 | 63| LOS_ERRNO_MUX_INVALID`<br>` LOS_ERRNO_MUX_PENDED | 失败 | 64 65#### LOS_MuxPend() 66 67```c 68UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout); 69``` 70 71**描述:** 72 73申请指定的互斥锁 74 75**参数:** 76 77| 名字 | 描述 | 78| :-------- | :--------------- | 79| muxHandle | 需要申请的互斥锁 | 80| timeout | 超时时间 | 81 82**返回值:** 83 84| 返回值 | 描述 | 85| :------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--- | 86| LOS_OK | 成功 | 87| LOS_ERRNO_MUX_INVALID`<br>` LOS_ERRNO_MUX_UNAVAILABLE `<br>` LOS_ERRNO_MUX_PEND_INTERR `<br>` LOS_ERRNO_MUX_PEND_IN_LOCK `<br>` LOS_ERRNO_MUX_TIMEOUT | 失败 | 88 89#### LOS_MuxPost() 90 91```c 92UINT32 LOS_MuxPost(UINT32 muxHandle); 93``` 94 95**描述:** 96 97释放指定的互斥锁 98 99**参数:** 100 101| 名字 | 描述 | 102| :-------- | :--------------- | 103| muxHandle | 需要释放的互斥锁 | 104 105**返回值:** 106 107| 返回值 | 描述 | 108| :------------------------------------------------------ | :--- | 109| LOS_OK | 成功 | 110| LOS_ERRNO_MUX_INVALID`<br>` LOS_ERRNO_MUX_PEND_INTERR | 失败 | 111 112### 软件设计 113 114**主要代码分析** 115 116在mutex_example函数中,通过LOS_MuxCreate函数创建了互斥锁,并创建的两个线程write_thread和read_thread。 117 118```c 119void mutex_example() 120{ 121 unsigned int thread_id1; 122 unsigned int thread_id2; 123 unsigned int ret = LOS_OK; 124 125 ret = LOS_MuxCreate(&m_mutex_id); 126 if (ret != LOS_OK) 127 { 128 printf("Failed to create Mutex\n"); 129 } 130 131 ret = CreateThread(&thread_id1, write_thread, NULL, "write_thread"); 132 if (ret != LOS_OK) 133 { 134 printf("Failed to create write_thread\n"); 135 return; 136 } 137 138 ret = CreateThread(&thread_id2, read_thread, NULL, "read_thread"); 139 if (ret != LOS_OK) 140 { 141 printf("Failed to create read_thread\n"); 142 return; 143 } 144} 145``` 146 147在write_thread线程函数中,先获得互斥锁,写入数据,并持有它时延迟3s。在read_thread线程函数中,延时1s后,申请互斥锁等待,线程被阻塞;3S后write_thread线程释放互斥锁,read_thread线程获得互斥锁,读取数据。 148 149```c 150void write_thread() 151{ 152 while (1) 153 { 154 LOS_MuxPend(m_mutex_id, LOS_WAIT_FOREVER); 155 156 m_data++; 157 printf("write_thread write data:%u\n", m_data); 158 159 LOS_Msleep(3000); 160 LOS_MuxPost(m_mutex_id); 161 } 162} 163 164void read_thread() 165{ 166 /*delay 1s*/ 167 LOS_Msleep(1000); 168 169 while (1) 170 { 171 LOS_MuxPend(m_mutex_id, LOS_WAIT_FOREVER); 172 printf("read_thread read data:%u\n", m_data); 173 174 LOS_Msleep(1000); 175 LOS_MuxPost(m_mutex_id); 176 } 177} 178``` 179 180## 编译调试 181 182### 修改 BUILD.gn 文件 183 184修改 `vendor/lockzhiner/lingpi/sample` 路径下 BUILD.gn 文件,指定 `a4_kernel_mutex` 参与编译。 185 186```r 187"a4_kernel_mutex", 188``` 189 190在主目录下输入编译命令。 191 192```shell 193hb build -f 194``` 195 196### 运行结果 197 198例程代码编译烧写到开发板后,按下开发板的RESET按键,通过串口软件查看日志,write_thread线程函数先写入数据阻塞3s,read_thread线程函数阻塞3s后读取数据。 199 200```r 201write_thread write data:1 202read_thread read data:1 203write_thread write data:2 204read_thread read data:2 205write_thread write data:3 206read_thread read data:3 207``` 208