本帖最后由 乘简 于 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
虽然程序执行慢了,但是可以得到正确的结果了,感谢平头哥的工单系统技术小二,不厌其烦给我解答。。。
下面一文很好理解多线程与抢占资源方面的文章
多个线程“打架抢夺”同一个资源,该如何让它们安分?
|