208|2

22

帖子

0

资源

一粒金砂(中级)

aos 多线程 与 互斥锁 [复制链接]

本帖最后由 乘简 于 2022-6-14 12:52 编辑

首先来看一段代码:

#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#include "aos/cli.h"
#include "main.h"
#include "app_init.h"
#include <drv/timer.h>

#define TAG "app"

volatile int n=0;
csi_timer_t g1_timer;//定义变量
static void g1_handler(csi_timer_t *timer_handle, void *arg)
{
	printf("%d\r\n",n);
	n=0;//为什么这句会时不时不执行呢?
	//printf("%d\r\n",n);
}

void my_test(void)
{
	csi_timer_init(&g1_timer, 0);//初始化定时器
	csi_timer_attach_callback(&g1_timer, g1_handler, NULL);//绑定回调函数
	csi_timer_start(&g1_timer, 1000000);//1000000每秒定时,单位为us,时间到自动执行回调函数
	while(1){
		n++;
	}
	csi_timer_stop(&g1_timer);
	csi_timer_detach_callback(&g1_timer);
	csi_timer_uninit(&g1_timer);
}

int main(void)
{
    board_yoc_init();
    LOGD(TAG, "%s\n", aos_get_app_version());
	my_test();
    return 0;
}

也就是每秒钟输出n的累加次数,执行为:

32767548
65535098
32767548
65535098
32767548
65535098
32767548
65535098
32767548
65535098
32767548
65535098
32767548
65535098

从执行结果来看,感觉定时器回调函数中的n=0;偶尔没有执行,其实原因是这样的,,在主函数中的n++;这句话,并不是一条指令就能执行完的,要3条指令才能执行完,

1)把n的值取出来放入寄存器中,

2)把寄存器+1,

3)把加1后的值存入n中,

那么在这3条指令是可能被定时器中断的,然后就出现了意想不到的问题了。。。

 

而正确的做法是,看下面的代码

/*
 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
 */


#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#include "aos/cli.h"
#include "main.h"
#include "app_init.h"
#include <drv/timer.h>

#define TAG "app"

static aos_mutex_t test_mutex;

volatile int n=0;
csi_timer_t g1_timer;//定义变量
static void g1_handler(csi_timer_t *timer_handle, void *arg)
{
	printf("%d\r\n",n);
	aos_mutex_lock(&test_mutex, AOS_WAIT_FOREVER);
	n=0;
	aos_mutex_unlock(&test_mutex);
}

void my_test(void)
{
	csi_timer_init(&g1_timer, 0);//初始化定时器
	csi_timer_attach_callback(&g1_timer, g1_handler, NULL);//绑定回调函数
	csi_timer_start(&g1_timer, 1000000);//1000000每秒定时,单位为us,时间到自动执行回调函数
	while(1){
		aos_mutex_lock(&test_mutex, AOS_WAIT_FOREVER);
		n++;
		aos_mutex_unlock(&test_mutex);
	}
	csi_timer_stop(&g1_timer);
	csi_timer_detach_callback(&g1_timer);
	csi_timer_uninit(&g1_timer);
}

int main(void)
{
    board_yoc_init();
    LOGD(TAG, "%s\n", aos_get_app_version());
	aos_mutex_new(&test_mutex);
	my_test();
    return 0;
}

执行结果:

668735
668682
668711
668711
668711
668711
668710
668711
668712
668711
668711
668711
668711
668711

虽然程序执行慢了,但是可以得到正确的结果了,感谢平头哥的工单系统技术小二,不厌其烦给我解答。。。

 

下面一文很好理解多线程与抢占资源方面的文章

多个线程“打架抢夺”同一个资源,该如何让它们安分?


回复

6797

帖子

0

资源

五彩晶圆(中级)

谢谢楼主的分享

请问楼主,这种aos 多线程 与互斥锁 现象会在什么情况下发生?应对措施还有其他方法么

点评

其实的方法肯定是有的,,比如:    详情 回复 发表于 2022-6-15 14:44

回复

22

帖子

0

资源

一粒金砂(中级)

本帖最后由 乘简 于 2022-6-15 14:45 编辑
Jacktang 发表于 2022-6-15 07:08 谢谢楼主的分享 请问楼主,这种aos 多线程 与互斥锁 现象会在什么情况下发生?应对措施还有其他方法么

其实的方法肯定是有的,,比如:

/*
 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
 */


#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#include "aos/cli.h"
#include "main.h"
#include "app_init.h"
#include <drv/timer.h>

#define TAG "app"

volatile int n=0,s=0;
csi_timer_t g1_timer;//定义变量
static void g1_handler(csi_timer_t *timer_handle, void *arg)
{
	printf("%d\r\n",n);
	s=1;
}

void my_test(void)
{
	csi_timer_init(&g1_timer, 0);//初始化定时器
	csi_timer_attach_callback(&g1_timer, g1_handler, NULL);//绑定回调函数
	csi_timer_start(&g1_timer, 1000000);//1000000每秒定时,单位为us,时间到自动执行回调函数
	while(1){
		if(s){
			s=0;
			n=1;
		}
		else n++;
	}
	csi_timer_stop(&g1_timer);
	csi_timer_detach_callback(&g1_timer);
	csi_timer_uninit(&g1_timer);
}

int main(void)
{
    board_yoc_init();
    LOGD(TAG, "%s\n", aos_get_app_version());
    my_test();
    return 0;
}

 


回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

最新文章 更多>>
    推荐帖子
    时钟配置问题

    如何在msp430fr5732上配置晶振为外部16m的晶振

    【主题月】为什么在开关电源中不能选用碳膜电阻?

    为什么在开关电源中不能选用碳膜电阻?而是要选择金属膜电阻?

    TEXT控件里的文字可以更改吗?

    请问TEXT控件里的文字可以更改吗?如果字体不一样,修改了字体,能不能改?谢谢

    ZigBee、WiFi、Bluetooth三种无线通讯技术应用特点

    ZigBee模块。zigbee又称为“紫蜂”,它是一种基于IEEE802.15.4标准的局域网协议,频段在2.4GHz,特点是距离近、应用简 ...

    分享些位操作干货

    嵌入式难免和芯片的寄存器打交道,操作寄存器需要用到位操作。 清除某位、置1某位这些基本操作就不说了,来点干货。 # ...

    在向SPI数据线写一位时,这一位要保持一定时间,针对不同晶振频率的MCU如何编程

    在向SPI数据线写一位时,这一位要保持一定时间,针对不同晶振频率的单片机用C语言如何 编程 来适应 不同频率的 单片机 以使此位 ...

    关闭
    站长推荐上一条 1/8 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表