【问题标题】:Shared Variable in pthreadpthread中的共享变量
【发布时间】:2021-06-22 06:39:45
【问题描述】:
#include<iostream>
#include<pthread.h>
#include<chrono>

struct Arg1{
    int x,y;
};
void * process(void * threadarg){
    int x,y;
    Arg1 * myArg1;
    myArg1 = (Arg1 *) threadarg;
    x = myArg1->x;
    y=myArg1->y;
    int i=0;
    while(i<500){
        x+=1;
        y+=2;
        i++;
    }
    myArg1->x=x;
    myArg1->y=y;
    pthread_exit(NULL);
}
using namespace std;

int main(){
    int x = 0;
    int y = 0;
    int n;
    cin>>n;
    Arg1 sharedObj;
    sharedObj.x=x;
    sharedObj.y=y;
    auto start = chrono::high_resolution_clock::now();
    pthread_t *threads = new pthread_t[n];
    for(int i=0;i<n;++i){
        pthread_create(&threads[i],NULL,process,(void *)&sharedObj);
    }
    for(int i=0;i<n;++i){
        pthread_join(threads[i],NULL);
    }

    cout<<sharedObj.x<<" "<<sharedObj.y<<"\n";
    auto stop = chrono::high_resolution_clock::now();
    auto duration = chrono::duration_cast<chrono::microseconds>(stop-start);
    cout<<duration.count()<<"\n";
}

我写了这段代码,看看使用共享变量是否会导致结果出现问题。

它的作用是——它首先询问用户线程数n。每个线程将共享变量 x 和 y 分别增加 1 和 2。变量通过使用相同的结构对象来共享。最后,我从 struct 对象中打印出 x 和 y 的值。

我在函数process 中看到了一个小的while 循环,无论线程数n 多少,我都能得到正确的结果。但是,对于较大的值,大约 5000,我有时会得到错误的结果。

另外,执行时间随着线程数量的增加而增加,我不明白这是因为不正确的多线程还是因为创建更多线程的开销。

提前感谢您的帮助。

【问题讨论】:

  • 如果您的 CPU 绑定线程多于您的计算机可用的物理线程,那么调度程序必须将逻辑线程换入和换出 CPU。这样做会产生开销(需要保存/恢复线程的状态)。因此,随着开销增加(更多线程),这将减少正在执行的有用工作量。关于在没有任何同步的情况下读取和写入共享变量,这是未定义的行为。
  • 多线程对对象的非同步、非只读、非原子访问的未定义行为。此外,您有多个内存泄漏,并且您正在以一种非常不可取的方式混合 C 和 C++,因此我建议您在尝试多线程之前先尝试学习单线程编程。
  • 您能否指出一些内存泄漏在哪里以及为什么代码似乎混合了 C 和 C++?是因为我使用了这么多指针吗?我这样做是因为这是我发现的唯一一种使用 pthread 的实现。
  • "...混合 C 和 C++..." 在 C++ 中,您可以使用 std::thread 进行线程处理,使用 std::vector 代替动态数组。我能看到的唯一内存泄漏是threads
  • 我认为我正在实现更接近架构(低级别)的东西,所以我会创建一个更好的程序。使用std::vectorstd::thread 似乎是一种懒惰的方法。感谢您指出。

标签: c++ pthreads shared-variable


【解决方案1】:

除非我们使用互斥体或某种方法来确保写入的原子性,否则我们不能保证我们会在 pthread 应用程序中获得正确的值。这是因为,同时写入会导致竞争条件,只有一个写入会影响共享变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 2013-02-11
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    相关资源
    最近更新 更多