RT-Thread 体验教程:3.有趣且实用的RT-Thread互斥量

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 时,两个变量 number1number2 是相等的,但后面就出现了不同步的情况。这是因为在 AddThread1_entry 中,两个变量的自增操作之间有明显的延时,导致 number1 自增后,线程 1 被挂起,运行线程 2,此时 number2 还未自增,因此 number2 一直比 number1 小。

使用互斥量进行同步

为了保证 number1number2 在所有线程中的自增操作保持同步,我们可以使用互斥量进行线程同步。

1. 在 rtconfig.h 中开启互斥量支持

确保在 rtconfig.h 中定义了 RT_USING_MUTEX 宏:

#define RT_USING_MUTEX

image.png

2. 声明并创建互斥量

在代码中声明一个互斥量,并在合适的地方进行初始化:
image.png

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. 编译并烧写

编译代码并将其烧写到设备上,验证结果。两个变量 number1number2 应该始终保持同步自增。
image.png
image.png

静态创建互斥量和线程

除了上述动态创建互斥量和线程,还可以使用静态方式进行创建:
image.png

编译并验证

编译代码并将其烧写到设备上,确认两个变量 number1number2 始终保持同步自增。
image.png

通过上述方法,我们成功地使用互斥量解决了线程间数据访问的同步问题,确保了共享数据的一致性。希望这个教程对你的 RT-Thread 开发有所帮助。

对应的 demo 源码, 请点击 RtosExPro at rtt_sync_metux

也可扫码关注博主同名公众号"不解之榬",回复 “RTT” 获取
不解之榬

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值