Linux下,多线程程序中对全局变量应当如何操作?

发布于 2022-09-11 18:41:23 字数 1724 浏览 14 评论 0

问题描述

有一个初始值为n的全局变量作为计数器,
然后用n个线程,每个线程将计数器减1,将这个计数器减少到0;
在n比较大的时候, 得不到正确结果.

使用了pthread线程和std::thread,尝试了用pthread_mutex, std::mutex, 以及__atomic_sub_fetch进行加锁或者原子减,都得不到正确结果

当n为10的时候,可以得到正确结果.
当n为100的时候,得不到正确结果.而在线程内延时10ms之后可以得到正确结果

我猜是共享资源这里出了问题,但是实在想不通,这个锁应该怎么加才是对的... 求各位Dalao解答一下`

相关代码

全局变量

int count = 100;
pthread_mutex_t mutex_pthread;
mutex mutex_std;

线程函数

void* writer(void* id) {

  cout << "Writer enter. " << (long)id << endl;
//this_thread::sleep_for(chrono::milliseconds(10));

//__atomic_sub_fetch(&count, 1, __ATOMIC_RELAXED);

//pthread_mutex_lock(&mutex_pthread);
//count--;
//pthread_mutex_unlock(&mutex_pthread);

  {
    lock_guard<mutex> lock_guard1(mutex_std);
    count--;
  }

  cout << "Writer exit. " << (long)id << ", count: " << count << endl;
  return NULL;
}

主函数

int main() {
  std::cout << "Hello, World!" << std::endl;

  pthread_mutex_init(&mutex_pthread, NULL);
  vector<pthread_t> writers;
  for (int i = 0; i < count; i++) {
    pthread_t th;
    pthread_create(&th, NULL, writer, (void*)i);
    writers.push_back(th);
  }


  for (int i = 0; i < count; i++) {
    void* ret;
    pthread_join(writers[i], &ret);
  }

  cout.flush();
  cerr << "All writers end. Count: " << count << endl;
  while (count);
  cerr << "All writers end. Count: " << count << endl;

  return 0;
}

你期待的结果是什么?实际看到的错误信息又是什么?

期待stderr中count输出的count为0;
实际输出为49;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凝望流年 2022-09-18 18:41:23

join的循环次数不对` count在线程中被改变了,所以部分线程没等到就退出了

这样的小城市 2022-09-18 18:41:23

实际上,我不太明白什么要设计成在各个线程的上下文里去操作count,这个count看上去应该是常量才合理。


多线程程序中对全局变量应当如何操作?

这里全局变量更一般的意思应该是多个线程上下文可能访问的公共资源。对于这种资源,我能想到的一些处理方式:

  1. 互斥访问(sem、mutex...)
  2. RCU
  3. 将资源设计成每线程(每CPU)资源
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文