当前位置: 首页 > 面试题库 >

在不同c文件中的pthread中访问全局变量

那正初
2023-03-14
问题内容

我有一个main.c,其全局变量名为int countboards。在main()中,我启动一个pthread,它侦听一个TCP连接并通过(progserver.c)运行该线程。意味着,该线程将永远不会返回。在main()中,输入rmmain(...)rm.c(RM
=资源管理器)中的函数。在rm.c中,我countboards在pthread的progserver.c中读取了此变量的内容(两者均可通过进行访问extern int countboards)。

因此,问题是,当我countboards在pthread中写入并且要在rm.c中写入此变量后要访问此变量时,它仍然具有旧值(在这种情况下为0而不是例如10)。为什么?

main.c:

int countboards;

int main(int argc, char** argv) {
  countboards = 0;
  pthread_t thread;
  pthread_create(&thread, NULL, startProgramserver, NULL);

  rmmain();

  return 0;
}

rm.c:

extern int countboards;

int rmmain(vhbuser* vhbuserlist, int countvhbuser,
       userio* useriolist, int countios, int usertorm, int rmtosslserver, int sslservertorm) {
  while(1) {
    int n;
    n=read(usertorm,buf,bufc); // blocks until command comes from the user
    ...
    board* b = findAFreeBoard(boardlist, countboards, usagelist); // here countboards should be >0, but it isn't
    ...
  }
}

programserver.c:

extern int countboards;
void* startProgramserver(void*) {
  ...
  sock = tcp_listen();
  ...
  http_serve(ssl,s, sslpipes);
}

static int http_serve(SSL *ssl, int s, void* sslpipes) {
  ...
  countboards = countboards + countboardscommands;
  ...
  // here countboards has the new value
}

问题答案:

您正在每个线程中看到一个缓存的副本。我建议声明一下,volatile int countboards除非那确实不是解决问题的好方法。

全球人有点邪恶。将指针传递给每个线程并与互斥锁进行同步会更好。

编辑: 为了扩大这一点,因为我昨晚很着急…

http://software.intel.com/zh-CN/blogs/2007/11/30/volatile-almost-useless-for-
multi-threaded-programming/

正如KasigiYabu在下面的评论中提到的那样,创建一个“上下文”结构,其中包含您希望在线程之间共享的所有信息,并将其pthread_create作为最后一个arg传递给您,这是一种合理的方法,并且在大多数情况下,我也是这样做的。



 类似资料:
  • 我在下面定义了一个全局js变量(@Url是ASP.Net MVC html帮助程序,它将转换为字符串值): 如何访问angular2组件中的rootVar?我曾经在Angular1.5中使用窗口服务,在angular2中有类似的方法吗? 具体来说,我想使用该rootVar变量来帮助在该组件中生成templateUrl:

  • 问题内容: 我有这个: 我如何才能实际修改全局变量g_c? 问题答案: 通过在访问它的函数中声明它: 在Python文档说这个,有关声明: 全局语句是一个声明,适用于整个当前代码块。

  • 问题内容: 如何设置变量,并使其在所有路由中都可用,至少在路由中的文件中可用。使用快速框架和 问题答案: 要创建全局变量,只需声明不带关键字的变量即可。(通常来说,这不是最佳做法,但在某些情况下可能会有用-请小心,因为它将使变量随处可见。) 这是visionmedia / screenshot-app的示例 文件 app.js : 文件 路由/ main.js

  • 如果我在我的main.js文件中有一个全局变量,我希望可以在由webpad捆绑到同一个构建/bundle.js中的打字稿文件中访问它,我该怎么做?我不能像我想象的那样直接访问它(最后它们在同一个捆绑包中)。我已经阅读了导出/导入/要求,但找不到如何在webpad捆绑包的上下文中应用它。

  • 问题内容: 我有一个main.go文件,其中有: 在我要声明,可在我的应用程序的任何地方访问的全局变量。有可能吗?我试过了: 但是,即使在同一包中,我也无法访问变量。 问题答案: 在顶层声明变量-在任何函数之外: 由于变量的名称以大写字母开头,因此在导入定义变量的包并使用包名对其进行限定时,变量将在当前包中通过其名称可用-在任何其他包中都可用。 这是另一个示例(同样在Go游乐场中:https :

  • 问题内容: 我有两个快速文件: 和 在main.swift中, 我最初设置为。 将I设置为,一切正常。 但是,如果我尝试通过 view 这样的简单调用从 view.swift进行 访问,则即使变量已更改,它也总是会获得,即使它在main.swift中也没有变化。 该方法在 main.swift 如下所示: 编辑 这是代码(翻译成意大利语:D) 在此先感谢Alberto 问题答案: Swift中的“