c - 通过函数调用扩展 C 中局部变量的范围

标签 c windows multithreading

我有一个库,它向用户提供函数调用,如下所示:

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 的可见性。

我知道上面的代码片段并不完美。只是为了证明我的意图... SendResponse() 尚未实现;-)。

我希望,有人可以提供一些如何“实现”SendResponse() 并保持线程安全的想法。

最佳答案

您可以在此处使用线程本地来保留 g_ID,而不是使用全局线程。据我了解,这将在以下情况下起作用:不同线程可能有多个并发调用 process() ,但 process() 方法如下所示 - SendResponse() 调用仅发生在 callback() 方法的范围内(运行时范围,而不是词法范围)。所示代码中确实如此。如果 HandleRequest 做了一些奇怪的事情,比如启动另一个线程然后返回(但你当然可以通过文档禁止它),那么这可能是不真实的。

另一种更经典的方法是将您关心的所有状态(例如 g_ID)封装到您所关心的 void *opaque_state * 或其他任何内容中。传递给回调,然后像 SendRespose() 这样的方法将其作为参数。如果您不喜欢 void *,您可以实现 opaque_state * 版本,而无需使用前向声明公开该结构的任何细节。

关于c - 通过函数调用扩展 C 中局部变量的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20992470/

相关文章:

windows - 在Windows Phone 8中播放音频时如何录制或获取音频?

windows - 适用于 Windows 和 Mac 的窗口管理器

multithreading - 是什么让 Python3 的打印函数线程安全?

c++ - 为什么 C++ 不使用 C++ 元素/样式重新实现 C 标准函数?

c - gcc 5编译fork()返回父pid 0吗?

c++ - 让程序运行缓慢

multithreading - 是否可以使用线程转储找到线程的创建时间?

c - C 程序上的未知类型名称 "list"

windows - MongoDB "The default storage engine ' wiredTiger' 不适用于此版本的 mongod "+ "..no/data/db 文件夹..”

java - 负载测试多线程系统与使用单独进程的系统 - 为什么线程版本要快得多?