先抛出问题:
有一全局变量,一个工作读,一个工作写,有没有问题?
先抛出答案,不倡议这么做。

临界资源:各工作/线程采取互斥的形式,实现共享的资源称作临界资源。属于临界资源的硬件串口打印、显示等,软件有音讯缓冲队列、变量、数组、缓冲区等。多任务/线程间应采取互斥形式,从而实现对这种资源的共享。
多任务/多线程状况下在写模块时,只须要封装进爱护机制即可。常见的爱护机制无关中断、信号量、互斥锁等。

最近做的几个我的项目遇到的一些非凡场景:

1.校时

定义全局变量

typedef struct{    /*应用软件工夫*/    unsigned int year;    unsigned char month;    unsigned char day;    unsigned char hour;         /*时     */    unsigned char minute;       /*分     */    unsigned char second;       /*秒     */    unsigned int millisecond;  /*毫秒*/    unsigned int microsecond;  /*微秒*/    unsigned int nanosecond;   /*纳秒*/       unsigned int u40mic;    int  delta;         /*日历时与本地RTC的差值*/    int  delta_rtc;        /*同步RTC与本地RTC的差值*/    int  delta_year;    /*用于操作系统年份保护*/    int  timeElapse;    /*零碎上电后运行了多少秒*/    char DateValid;     /*年月日无效标识,1为无效*/    char TimeValid;     /*时分秒无效标记,1为无效*/    char BusVaild;         /*总线工夫无效, 1为无效, 用于飞参授时及文件夹创立*/}STRUCT_CORE_TIME;STRUCT_CORE_TIME gst_TimeState;
int TIME_Regulate_Time(int year, int month, int date, int hour, int minute, int second){    struct timespec NewSetTime;    struct tm   DownTime;    SYSTEM_TIME_TYPE sys_Time = 0;    RETURN_CODE_TYPE retCode;        if((year < 2000)||(year > 2255))        return -1;    if((month < 1) || (month > 12))        return -2;    if((date < 1) || (date>31))        return -3;    if((hour > 23) || (minute > 59) || (second > 59))        return -4;    /*当超出年限时,获取delta*/    if(year > 2100){        if(((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)){            gst_TimeState.delta_year = year - 2096;            year = 2096;        }else{            gst_TimeState.delta_year = year - 2100;            year = 2100;        }    }else{        gst_TimeState.delta_year = 0;    }    GET_TIME(&sys_Time, &retCode);    DownTime.tm_hour = hour;    DownTime.tm_min = minute;    DownTime.tm_sec = second;    DownTime.tm_mday = date;    DownTime.tm_mon = month - 1;    DownTime.tm_year = year - 1900;    DownTime.tm_isdst = 0;            /*设置为非夏令时*/    NewSetTime.tv_sec = mktime(&DownTime);    /*工夫间接用delta保护,不波及零碎工夫*/    gst_TimeState.delta = NewSetTime.tv_sec - sys_Time / Time_1S;    /*LOG4C日志零碎工夫更新*/    sd_settimeofday(gst_TimeState.delta);    gst_TimeState.TimeValid = 1;    gst_TimeState.DateValid = 1;    return 0;}void TIME_Gather_Time(){    struct timespec NewSetTime;    struct tm   DownTime;    SYSTEM_TIME_TYPE sys_Time = 0;    RETURN_CODE_TYPE retCode;    GET_TIME(&sys_Time, &retCode);    NewSetTime.tv_sec = sys_Time / Time_1S + gst_TimeState.delta;    localtime_r(&NewSetTime.tv_sec, &DownTime);    gst_TimeState.year = DownTime.tm_year + 1900 + gst_TimeState.delta_year;    gst_TimeState.month = DownTime.tm_mon + 1;    gst_TimeState.day = DownTime.tm_mday;    gst_TimeState.hour = DownTime.tm_hour;    gst_TimeState.minute = DownTime.tm_min;    gst_TimeState.second = DownTime.tm_sec;        gst_TimeState.millisecond = sys_Time / 1000000 % 1000;    gst_TimeState.microsecond = sys_Time / 1000 % 1000;    gst_TimeState.nanosecond = sys_Time % 1000;    gst_TimeState.u40mic = ((gst_TimeState.hour * 3600 + gst_TimeState.minute * 60 + gst_TimeState.second)*1000            + gst_TimeState.millisecond)*25;}

校时线程做如下的周期调用:

if(stBusTime.delta和gst_TimeState.delta相差2秒){                /*校对利用工夫*/        Ret = TIME_Regulate_Time(stBusTime.year + 2000, stBusTime.month, stBusTime.day, stBusTime.hour, stBusTime.minute, stBusTime.second);        /*只有VCM校时,就给DLR也校时。有的时候音视频文件创建太早,导致视频头内容有问题*/        TIME_Gather_Time();  /*立即TIME_Gather_Time数据,更新gst_TimeState构造体所有内容*/}

另一个线程间接取全局变量gst_TimeState内的年月日时分秒。
这种状况实际上是不加爱护的一个线程读,另一个线程写,然而不加爱护也能应用的起因有两点:
1.外界有卫星相对工夫更新gst_TimeState本地工夫
2.对工夫的精度要求不高

获取卡状态

嵌入式零碎下,工作1进行获取卡状态操作:

static void Msg_04_Process(void * const Handler, unsigned char * const Message, int const LenBytes){    DEVICE_INNER_TYPE *pDevice = (DEVICE_INNER_TYPE*)Handler;    /*04音讯解决(周期接管)*/    memcpy(&DLR_2_CPM_04, Message, sizeof(DLR_2_CPM_04));    /*IDR端的定义是相同的*/    pDevice->CardState = !DLR_2_CPM_04.Card_State;}

工作2周期获取卡状态,并进行一些操作

int PSSS_DLR_Card_State(void * const Handler){    DEVICE_INNER_TYPE *pDevice = (DEVICE_INNER_TYPE*)Handler;    int cardState = 0;    cardState = pDevice->CardState;    return cardState;}

利用场景:
Msg_04_Process获取卡号的周期是2秒,而PSSS_DLR_Card_State大概20ms就要被调用一次。
计划:
1.给pDevice->CardState加信号量爱护
2.PSSS_DLR_Card_State中屡次判断pDevice->CardState的值,例如间断3次是同一个值才示意获取胜利