我想知道是否有人看到任何可能导致此代码出现问题的内容。我知道还有其他方法/ API调用,我可以用来做到这一点,但我试图为我自己的平台独立奠定基础? /跨平台互斥框架。
显然我需要做一些#ifdef并为Win32 Sleep()和GetCurrentThreadID()调用定义一些宏......
typedef struct aec {
unsigned long long lastaudibleframe; /* time stamp of last audible frame */
unsigned short aiws; /* Average mike input when speaker is playing */
unsigned short aiwos; /*Average mike input when speaker ISNT playing */
unsigned long long t_aiws, t_aiwos; /* Internal running total */
unsigned int c_aiws, c_aiwos; /* Internal counters */
unsigned long lockthreadid;
int stlc; /* Same thread lock count */
} AEC;
char lockecho( AEC *ec ) {
unsigned long tid=0;
static int inproc=0;
while (inproc) {
Sleep(1);
}
inproc=1;
if (!ec) {
inproc=0;
return 0;
}
tid=GetCurrentThreadId();
if (ec->lockthreadid==tid) {
inproc=0;
ec->stlc++;
return 1;
}
while (ec->lockthreadid!=0) {
Sleep(1);
}
ec->lockthreadid=tid;
inproc=0;
return 1;
}
char unlockecho( AEC *ec ) {
unsigned long tid=0;
if (!ec)
return 1;
tid=GetCurrentThreadId();
if (tid!=ec->lockthreadid)
return 0;
if (tid==ec->lockthreadid) {
if (ec->stlc>0) {
ec->stlc--;
} else {
ec->lockthreadid=0;
}
}
return 1;
}
答案 0 :(得分:3)
不,不是,AFAIK如果没有一些低级atomic操作(RMW,Test and Set等等),您无法使用纯C代码实现互斥锁。你的特定例子,考虑如果上下文切换在有机会设置inproc
之前中断第一个线程会发生什么,然后第二个线程将恢复并将其设置为1
,现在两个线程都“认为”他们拥有对结构的独占访问权限......这只是你的方法可能出错的许多事情之一。
另请注意,即使线程有机会设置inproc
,也不保证赋值是原子的(在分配变量的过程中可能会中断)。
答案 1 :(得分:1)
正如mux指出的那样,由于许多竞争条件,您提出的代码不正确。您可以使用像“比较和设置”这样的原子指令来解决这个问题,但无论如何您都需要为每个平台单独定义。您最好只定义一个高级“锁定”和“解锁”界面,并使用平台提供的任何内容实现那些。