【发布时间】:2018-10-18 13:00:51
【问题描述】:
我一直在用 C 语言开发基于 RTOS 的嵌入式软件,我遇到了一个关于从多个线程访问共享资源的问题。我有两个问题。第一个是在状态机中设置和获取状态变量的值。下面是 StateMachine "object" 的头文件:
typedef enum{
STATE_01,
STATE_02,
STATE_03,
STATE_04
}state_e;
// state machine instance
typedef struct{
state_e currState;
}StateMachine;
extern state_e GetState(StateMachine*);
extern void SetState(StateMachine*, state_e);
访问方法的实现如下:
state_e GetState(StateMachine *sm){
return sm->currState;
}
void SetState(StateMachine *sm, state_e state){
sm->currState = state;
}
我的问题是我不确定是否应该使用互斥锁来控制对状态变量的访问。我的意思是在 32 位 MCU 上读取和写入 32 位变量是原子操作。
第二个问题涉及读取包含无符号 32 位整数的数组的一项值,其中每个位存储一位变量的值。 在这里,我再次不确定是否有必要使用互斥锁。出于与上述相同的原因,我认为不会,但我想听听一些更有经验的程序员的意见。位数组“对象”的相关头文件:
typedef struct{
uint32_t BitsArray[NO_WORDS];
}BitsArray;
extern uint32_t GetWordValue(BitsArray*, uint8_t);
访问方法实现:
uint32_t GetWordValue(BitsArray *ba, uint8_t word){
return *(ba->BitsArray + word);
}
感谢您的任何想法。
【问题讨论】:
-
您正在多个并发执行上下文之间共享状态机的当前状态?那么你有一个比变量访问的原子性更大的问题。帮自己一个忙,然后回去仔细寻找替代设计。
-
^^^ @andymango 所说的。如果我需要操作 SM,我通常将事件(生产者-消费者队列)排队到一个线程中,该线程可以单独访问状态数据。其他任何事情都会很快变成无法调试的混乱。
-
此外,您的问题的答案部分取决于目标系统是否具有多个 CPU 内核。如果它有多个,那么同时在不同内核上运行的不同线程可能对内存中的内容有不同的看法。 (谷歌的“缓存一致性”。)在这种情况下,您的 RTOS 有责任为您提供在不同线程之间安全共享数据所需的工具。
标签: c multithreading embedded rtos