账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    Linux下,多线程程序中对全局变量应当如何操作?
    27
    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;

    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 11 元积分
        全部回答
    • 0
    • 月牙笑眼 普通会员 1楼

      在Linux下,多线程程序中对全局变量的操作应当谨慎。全局变量可以在多个线程中访问,因此在编写多线程程序时需要特别小心。以下是一些基本的建议:

      1. 在函数中声明全局变量:在函数中声明全局变量是非常好的做法,因为它可以确保每个线程都在自己的作用域内使用变量。

      cpp int globalVariable; void function() { globalVariable = 10; // 这里声明全局变量 }

      1. 使用局部变量:如果必须在多个线程中共享一个全局变量,可以使用局部变量。但是,使用局部变量需要小心,因为它们会在每个线程中保存各自的副本。

      cpp int globalVariable = 10; // 这里声明全局变量 void function() { globalVariable = 20; // 这里声明全局变量 localVariable = globalVariable; // 使用局部变量 }

      1. 使用线程安全的数据结构:在多线程环境中,使用线程安全的数据结构可以避免全局变量的共享问题。

      cpp std::vector<int> threadSafeArray; // 使用线程安全的数据结构 void function() { for (int i = 0; i < threadSafeArray.size(); i++) { threadSafeArray[i] = 20; // 使用线程安全的数据结构 } }

      1. 使用互斥锁:互斥锁是一种同步机制,可以防止多个线程同时访问共享资源。在多线程环境中,可以使用互斥锁来保护全局变量。

      cpp int globalVariable = 10; // 这里声明全局变量 互斥锁 lock; // 创建互斥锁对象 void function() { while (true) { lock.lock(); // 获取互斥锁 if (lock.isHeld()) { globalVariable = 20; // 使用线程安全的数据结构 lock.unlock(); // 解锁互斥锁 } else { break; // 等待另一个线程释放锁 } } }

      总的来说,在多线程程序中对全局变量的操作应当谨慎,以确保每个线程都在自己的作用域内使用变量,并且避免全局变量的共享问题。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部