为啥我的线程函数中的局部变量会被其他线程中断?

Posted

技术标签:

【中文标题】为啥我的线程函数中的局部变量会被其他线程中断?【英文标题】:Why does the local variable in my thread function get interrupted by other threads?为什么我的线程函数中的局部变量会被其他线程中断? 【发布时间】:2019-07-29 13:56:56 【问题描述】:

我创建了几个线程并行执行以下线程函数,线程函数的输入参数是一个整数。 不同的线程得到不同的整数。在 thread 函数中,我定义了一个局部变量 thread_index 来接受这个将在计算中使用的整数。我的问题是这些局部变量会与其他线程的变量混淆,我认为这不应该发生。事实上,每个线程函数中都有一个循环,第一次尝试循环对所有线程都可以,但之后,局部变量“thread_index”就搞砸了。我使用信号量屏障来保护计算过程,但这不应该是我当前的问题。 所有未声明的变量都是在主函数中预定义的。我不明白为什么局部变量会被其他人打断。

以下是线程创建过程,其中N为整数,控制线程数,pthread_t t[N/2]。 for(long thread_index = 0;thread_index

void *exchange_swap(void *ptharg)
    // cout<<"num_phases "<<num_phases<<endl;
    long thread_index = (long) ptharg;
    for (phase = 1; phase <= num_phases;)
    

        int num_groups = pow(2, (phase-1) % num_stages);
        // cout<<num_groups<<endl;
        int group_size = N / num_groups;
        int gindex = (thread_index) / (group_size / 2);
        int mindex = (thread_index) % (group_size / 2);

        int group_start = gindex * group_size;
        int group_end = (gindex + 1) * group_size - 1;

        int data1 = group_start + mindex;
        int data2 = group_end - mindex;
        // swap
        int temp;
        if (sortArray[data1]>sortArray[data2])
        
            temp = sortArray[data1];
            sortArray[data1] = sortArray[data2];
            sortArray[data2] = temp;
        

        sem_wait(&s);
        cout<<"Thread "<<thread_index+1<<" finished stage "<<(phase - 1) / num_stages + 1<<" phase "<<(phase-1) % num_stages + 1<<endl;
        finished_job++;
        if (finished_job == N/2)
            finished_job = 0;
            phase++;
            for (int i = 0; i < N; ++i)
            
                cout<<sortArray[i]<<" ";
            
            cout<<endl;
            sem_post(&barrier);
        
        sem_post(&s);
        sem_wait(&barrier);
        sem_post(&barrier);
    
    return NULL;

【问题讨论】:

您确定您的意思是long thread_index = (long) ptharg; 而不是long thread_index = *(long*) ptharg; 如何创建线程?你能创建一个minimal reproducible example 给我们看吗?还有你为什么不用std::thread(我猜这里,不过好像你没用)。 是的,我使用 long thread_index = (long) ptharg,我尝试了您的建议,但出现了分段错误(核心转储)。我还怀疑我在内部传递了一个指针,因此在一段时间后,变量对所有人都保持不变。但我不知道问题到底出在哪里。 for(long thread_index = 0;thread_index @phonetagger 不幸的是,OP 在评论中添加了线程创建(而不是编辑问题,因此使代码难以阅读)但 OP 正在传递 value。使用 C 线程函数时,通常将值转换为指针,而在线程函数内部则相反。 【参考方案1】:

使用std::thread 传递值会更容易、更“自然”:

std::vector<std::thread> threads(N / 2);  // Create a vector of N/2 threads

// For each thread in the vector
for (unsigned thread_index = 0; thread_index < threads.size(); ++thread_index)

    // Create the thread
    threads[thread_index] = std::thread(exchange_swap, thread_index);


// Possibly do other work...

// Again for each thread (thread index no longer needed)
for (auto& thread : threads)

    // Wait for it to end
    thread.join();

那么线程函数就是一个简单的函数,按值取索引,不返回值:

void exchange_swap(unsigned thread_index)
    ...


正如我在评论中所说,在这种情况下,像你一样(通过强制转换)传递值是可以的。

【讨论】:

请注意,在创建第一个线程和最后一个线程 join() 之间的任何异常(或以任何其他方式离开本地范围)都会终止您的应用程序(在 std::thread::~thread() 中) 我使用了您的代码,但问题仍然存在。 -..- 不好意思,看来你是想给出更好的编码方式,我误会了。 最后,我解决了。我的问题是关于我不适当的信号量使用。我应该在每个循环之前添加另一个信号量屏障。不过,还是感谢大家的帮助!

以上是关于为啥我的线程函数中的局部变量会被其他线程中断?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Django 中使用线程局部变量不好?

ThreadLocal源码分析

python 线程中的局部变量ThreadLocal

线程局部存储主要用来干啥的?

线程局部存储的Win32实现

多线程访问全局变量和局部变量