gpt4 book ai didi

c++ - 全局静态 bool 指针使用 pthread 导致段错误

转载 作者:行者123 更新时间:2023-11-30 04:38:45 28 4
gpt4 key购买 nike

pthread 编程的新手,在处理 C++&C 混合代码时遇到此错误。

我所做的是在c++代码创建的线程中调用c代码。线程中使用了一个静态 bool 指针 is_center 并且应该在线程结束时释放。

但是我注意到,每次程序处理到c函数时, bool 指针的值都会改变,然后由于free()而发生段错误。并且只有在使用 c 代码时才会出现此问题。去掉c代码,多线程c++部分运行良好。

详细代码如下:

static bool *is_center;

// omit other codes in between ...

void streamCluster( PStream* stream)
{
// some code here ...
while(1){
// some code here ...
is_center = (bool*)calloc(points.num,sizeof(bool));

// start the parallel thread here.
// the c code is invoked in this function.
localSearch(&points,kmin, kmax,&kfinal); // parallel

free(is_center);
}

而使用parallel的函数如下(我的c代码是在每个线程中调用的):

void localSearch( Points* points, long kmin, long kmax, long* kfinal ) {
pthread_barrier_t barrier;
pthread_t* threads = new pthread_t[nproc];
pkmedian_arg_t* arg = new pkmedian_arg_t[nproc];

pthread_barrier_init(&barrier,NULL,nproc);

for( int i = 0; i < nproc; i++ ) {
arg[i].points = points;
arg[i].kmin = kmin;
arg[i].kmax = kmax;
arg[i].pid = i;
arg[i].kfinal = kfinal;
arg[i].barrier = &barrier;

pthread_create(threads+i,NULL,localSearchSub,(void*)&arg[i]);
}

for ( int i = 0; i < nproc; i++) {
pthread_join(threads[i],NULL);
}

delete[] threads;
delete[] arg;
pthread_barrier_destroy(&barrier);
}

最后调用我的 C 代码的函数:

void* localSearchSub(void* arg_) {                                                                                                                                                        

int eventSet = PAPI_NULL;
begin_papi_thread(&eventSet);

pkmedian_arg_t* arg= (pkmedian_arg_t*)arg_;
pkmedian(arg->points,arg->kmin,arg->kmax,arg->kfinal,arg->pid,arg->barrier);

end_papi_thread(&eventSet);

return NULL;
}

从 gdb 中,我得到的 is_center 是:

Breakpoint 2, localSearchSub (arg_=0x600000000000bc40) at streamcluster.cpp:1711
1711 end_papi_thread(&eventSet);
(gdb) s

Hardware watchpoint 1: is_center

Old value = (bool *) 0x600000000000bba0
New value = (bool *) 0xa93f3
0x400000000000d8d1 in localSearchSub (arg_=0x600000000000bc40) at streamcluster.cpp:1711
1711 end_papi_thread(&eventSet);

有什么建议吗?提前致谢!

关于代码的一些新信息:对于c代码,我使用的是PAPI包。我编写自己的 papi 包装器来初始化和读取系统计数器。代码如下:

void begin_papi_thread(int* eventSet)                                                                                                                                                     
{
int thread_id = pthread_self();
// Events
if (PAPI_create_eventset(eventSet)) {
PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);
printf("*** ERROR *** Failed to create event set for thread %d: %s\n.", thread_id, error_string);
}
if((return_value = PAPI_add_events(*eventSet, event_code, event_num)) != PAPI_OK)
{
printf("*** ERROR *** Failed to add event for thread %d: %d.\n", thread_id, return_value);
}
// Start counting
if ((return_value = PAPI_start(*eventSet)) != PAPI_OK) {
PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);
printf("*** ERROR *** PAPI failed to start the event for thread %d: %s.\n", thread_id, error_string);
}
}
void end_papi_thread(int* eventSet)
{
int thread_id = pthread_self();
int i;

long long * count_values = (long long*)malloc(sizeof(long long) * event_num);
if (PAPI_read(*eventSet, count_values) != PAPI_OK)
printf("*** ERROR *** Failed to load count values.\n");

if (PAPI_stop(*eventSet, &dummy_values) != PAPI_OK) {
PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);
printf("*** ERROR *** PAPI failed to stop the event for thread %d: %s.\n", thread_id, error_string);
return;
}
if(PAPI_cleanup_eventset(*eventSet) != PAPI_OK)
printf("*** ERROR *** Clean up failed for the thread %d.\n", thread_id);
}

最佳答案

我认为您发布的代码不足以真正理解您的问题,但您将 is_center 声明为全局看起来很可疑。我假设您在多个地方使用它,可能是通过多个线程(localSearchSub 提到它,这是您的工作线程函数)。

如果 is_center 被多个线程读取或写入,您可能希望使用 pthread mutex 来保护它.你说它“在线程完成时释放”,但你应该知道有 nprocs 线程,看起来它们都在 is_center[points] 数组上工作 bool 值。如果 points != nproc,这可能是一件坏事 [1]。每个线程应该在自己的数组上工作,localSearch 应该聚合结果。

xxx_papi_thread 函数在 Google 上没有任何搜索结果,所以我只能想象它是您自己的...如果问题出在其中,我们不太可能为您提供帮助: )

[1]:即使 points == nproc,也不一定可以从多个线程写入数组的不同元素(它取决于编译器和处理器)。安全起见,使用互斥量。

另外,这被标记为 C++。你能用 vector 替换 calloc 和动态数组(使用 new)吗?它最终可能更容易调试,而且最终肯定更容易维护。你为什么讨厌并想要惩罚你代码的读者? ;)

关于c++ - 全局静态 bool 指针使用 pthread 导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2982757/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com