【发布时间】:2014-01-08 10:07:36
【问题描述】:
我有一个为用户提供函数调用的库,如下所示:
int* g_ID = NULL;
void processing(int p1, char p2)
{
int ID = newID();
g_ID = &ID;
callback(p1, p2);
return ID;
}
void SendResponse()
{
sendID(*g_ID);
}
用户通过使用签名void (f*)(int p1, char p2) 注册其回调函数来设置其应用程序,并且不应该知道库内部使用的 ID。所以用户空间代码看起来像:
main()
{
RegisterCallback(HandleRequest);
while (inProgress())
sleep(1); /* just sleep here */
}
void (HandleRequest*)(int val1, char val2)
{
/* ... do something user specific ... */
SendResponse();
return;
}
这里的问题是,库(处理 ID 和 g_ID 不是线程安全的)!!用户的回调由其他库函数作为线程异步调用。多个线程可以以这种方式并行执行。但我不会让用户查看图书馆内部 ID。
我知道上面的代码 sn-ps 并不完美。这只是为了证明我的意图...SendResponse() 尚未实现;-)。
我希望,有人可以提供一些想法来“实现”SendResponse() 并保持线程安全。
【问题讨论】:
-
增加局部变量生命周期的唯一方法是使其成为
static。但是,这样做的缺点是,函数的所有调用都将具有完全相同的变量,每个函数调用都不会是“本地”的。 -
嗯,首先,使用指向局部变量的指针是不好的——它肯定会在调用返回后不久被覆盖。您应该改用
malloc或等效项,或@Joachim 建议的static关键字。至于线程安全,如果你能够使用 C11,你可以使用新的thread_local关键字。 -
我忘了说,动态内存分配是不允许的:-/ 一切都必须在编译时“分配”。
-
static thread_local应该可以工作(再次假设您可以使用 C11)。 -
好吧,不幸的是,
thread_local不可用,因为我使用的是 gcc 4.6,而 C11 首先是 gcc 4.8.1 正式可用的(我从其他线程得到的;甚至不确定 C11到目前为止是官方的,似乎只有 C++11)。
标签: c windows multithreading