问题是我有两个线程。一个线程只设置一些请求标志,另一个线程重置请求标志。 因此两个线程都有对标志的写访问权。我试图在没有同步的情况下这样做。
这是我实施的内容,我无法察觉它是如何出错的。
volatile uint32_t g_FORM_Requests;
#define FORM_REQUEST(X) \
do { \
if (g_FORM_Requests) \
{ \
g_SHELL_Print("Server is busy executing previous requests..."); \
} \
else \
{ \
g_FORM_Requests=(X); \
} \
} while (0x00U)
void * SERVER_Thread( void * Data)
{
uint32_t Snapshot;
while (!Done)
{
/* Take a snapshot of requests. */
Snapshot=g_FORM_Requests;
Execute(Snapshot);
g_FORM_Requests ^= Snapshot;
}
return (NULL);
}
表单通过调用SERVER_Thread
宏向FORM_REQUEST(X)
发出请求。 g_FORM_Requests
中的每个位都是单独任务的执行请求标志。这些任务的执行顺序无关紧要。
我是否正确地认为它会正常工作?如果没有,问题出在哪里?
编辑1:
volatile
关键字可确保在SERVER_Thread
结束时再次读取g_FORM_Requests
,然后再将Snapshot
与其进行异或。这意味着如果FORM_REQUEST()
在更改g_FORM_Requests
的过程中被中断,则不会导致错误行为,因为只有Snapshot
中设置的位才会从中删除。
问题不在于我们是否可以使用volatile关键字作为障碍。我正在利用这样一个事实:我的一个线程只将零转换为1,而另一个线程将其转换为零。因此g_FORM_Requests
变量本身充当锁,并且每个线程中临界区的部分执行不成问题......