为啥我的线程函数中的局部变量会被其他线程中断?
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()
中)
我使用了您的代码,但问题仍然存在。 -..-
不好意思,看来你是想给出更好的编码方式,我误会了。
最后,我解决了。我的问题是关于我不适当的信号量使用。我应该在每个循环之前添加另一个信号量屏障。不过,还是感谢大家的帮助!以上是关于为啥我的线程函数中的局部变量会被其他线程中断?的主要内容,如果未能解决你的问题,请参考以下文章