• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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