RT-Thread 互斥量使用教程
在多线程环境中访问共享数据时,如果不使用适当的线程同步机制,可能会导致数据不一致的问题。本文将通过一个简单的示例,介绍如何在 RT-Thread 中使用互斥量来解决线程同步问题。
未使用互斥量的线程示例
以下代码展示了在没有使用互斥量进行线程同步的情况下,两个线程对同一数据进行操作的情况:
rt_thread_t sampleThread1;
rt_thread_t sampleThread2;
static uint8_t number1 = 0, number2 = 0;
void AddThread1_entry(void* parameter)
{
while (1)
{
number1++;
rt_thread_mdelay(100);
number2++;
}
}
void AddThread2_entry(void* parameter)
{
while (1)
{
if (number1 != number2)
{
rt_kprintf("\r\nnumber1(%d) != number2(%d)", number1, number2);
}
else
{
rt_kprintf("\r\nnumber1 == number2, is %d", number1);
}
number1++;
number2++;
rt_thread_mdelay(1000);
}
}
int SampleTaskCreate(void)
{
sampleThread1 = rt_thread_create("sampleThread1",
AddThread1_entry,
RT_NULL,
256,
4,
10);
if (sampleThread1 != RT_NULL)
{
rt_thread_startup(sampleThread1);
}
else
{
return 0;
}
sampleThread2 = rt_thread_create("sampleThread2",
AddThread2_entry,
RT_NULL,
256,
2,
10);
if (sampleThread2 != RT_NULL)
{
rt_thread_startup(sampleThread2);
return 1;
}
return 0;
}
INIT_APP_EXPORT(SampleTaskCreate);
其运行结果如下:
number1 == number2, is 0
number1(11) != number2(10)
number1(22) != number2(21)
number1(33) != number2(32)
number1(44) != number2(43)
number1(55) != number2(54)
...
可以看到,第一次进入 AddThread2_entry
时,两个变量 number1
和 number2
是相等的,但后面就出现了不同步的情况。这是因为在 AddThread1_entry
中,两个变量的自增操作之间有明显的延时,导致 number1
自增后,线程 1 被挂起,运行线程 2,此时 number2
还未自增,因此 number2
一直比 number1
小。
使用互斥量进行同步
为了保证 number1
和 number2
在所有线程中的自增操作保持同步,我们可以使用互斥量进行线程同步。
1. 在 rtconfig.h
中开启互斥量支持
确保在 rtconfig.h
中定义了 RT_USING_MUTEX
宏:
#define RT_USING_MUTEX
2. 声明并创建互斥量
在代码中声明一个互斥量,并在合适的地方进行初始化:
3. 在线程中使用互斥量
修改线程函数,在对共享变量进行操作时,使用互斥量进行保护:
void AddThread1_entry(void* parameter)
{
while (1)
{
if (RT_OK == rt_mutex_take(&mutex_create_sync, RT_WAITING_FOREVER))
{
number1++;
rt_thread_mdelay(100);
number2++;
if (RT_OK != rt_mutex_release(&mutex_create_sync))
{
rk_kprintf("\r\nmutex_create_sync release failed");
}
}
}
}
void AddThread2_entry(void* parameter)
{
while (1)
{
if (RT_OK == rt_mutex_take(&mutex_create_sync, RT_WAITING_FOREVER))
{
if (number1 != number2)
{
rt_kprintf("\r\nnumber1(%d) != number2(%d)", number1, number2);
}
else
{
rt_kprintf("\r\nnumber1 == number2, is %d", number1);
}
number1++;
number2++;
rt_thread_mdelay(1000);
if (RT_OK != rt_mutex_release(&mutex_create_sync))
{
rk_kprintf("\r\nmutex_create_sync release failed");
}
}
}
}
4. 编译并烧写
编译代码并将其烧写到设备上,验证结果。两个变量 number1
和 number2
应该始终保持同步自增。
静态创建互斥量和线程
除了上述动态创建互斥量和线程,还可以使用静态方式进行创建:
编译并验证
编译代码并将其烧写到设备上,确认两个变量 number1
和 number2
始终保持同步自增。
通过上述方法,我们成功地使用互斥量解决了线程间数据访问的同步问题,确保了共享数据的一致性。希望这个教程对你的 RT-Thread 开发有所帮助。
对应的 demo 源码, 请点击 RtosExPro at rtt_sync_metux
也可扫码关注博主同名公众号"不解之榬",回复 “RTT” 获取