这是在pthread_join中提供段错误的函数:
void call_merge()
{
int no_runs = No_sub_seq;
int no_joins=no_runs-1;
int magic1=0,j=0,inc = 1;
int temp_runs = no_runs/2;
int i,k;
while(temp_runs!=0)
{
magic1=0;
std::list<pthread_t> threadList;
pthread_t thread;
for(i=0;i<=temp_runs-1;i++)
{
if((magic1 + inc) <= no_joins)
{
data *d=(data *)malloc(sizeof(data));
d->a=magic1;
d->b=magic1+inc;
d->c=inc;
pthread_create(&thread,NULL,(void* (*)(void*))merge, (void*)d);
threadList.push_front(thread);
}
magic1 = magic1 + (inc * 2);
}
std::list<pthread_t>::iterator m;
for(m=threadList.begin();m!=threadList.end();m++)
pthread_join(*m,NULL);
if((no_runs % 2) != 0)
temp_runs++;
no_runs = temp_runs;
temp_runs = no_runs/2;
inc = inc * 2;
}
}
这里是合并功能
void merge(void *param)
{
data *d=(data *)param;
int low=Sq[d->a],high;
int mid=Sq[d->b]-1;
if(Sq[d->b + d->c]==0)
high=size-1;
else
high=Sq[d->b + d->c]-1;
int k;
int i=0;
int j=low;
while(j<=mid)
b[i++]=a[j++];
i=0; k=low;
while (k<j && j<=high)
if (b[i]<=a[j])
a[k++]=b[i++];
else
a[k++]=a[j++];
while (k<j)
a[k++]=b[i++];
}
上述代码中调用的合并函数简单地合并使用参数d-> a,d-> b,d-> c传递的子阵列。并且在合并函数中没有写入线程代码。当没有线程并且给出输入数组的排序序列时,上面的程序工作正常。当我尝试使用gdb调试它时,它在pthread_join()中显示了一个segault。我无法弄清楚为什么会这样呢???提前谢谢
答案 0 :(得分:2)
您对pthread_create()的一次调用可能会失败,例如因为你超过了每个进程的线程总数限制。
在这种情况下,thread
包含未定义的值。由于您忽略了错误,因此您可以继续将未定义的值存储在列表中,然后再在其上调用pthread_join(),这会导致段错误。
编辑:既然您处理了来自pthread_create()
的错误,则段错误已经消失,但您的某些线程仍然无法创建,因此无法执行其工作。这就是为什么您的代码适用于1000
范围,但范围不是10000
的原因。
您的设计似乎非常适合thread pooling,即产生固定数量的线程,并在完成当前任务后立即为其提供更多工作。有关使用POSIX线程的池实现,请参阅here或there。
答案 1 :(得分:0)
您在什么范围定义threadList
对象?您push_front
新创建的线程进入列表但在您的代码中我既没有看到联接线程的显式erase
,也没有看到整个线程列表的RAII删除。由于你遍历了整个线程列表,你可能会多次为已经取消的线程调用pthread_join
...