【问题标题】:pthreads_create causing segment faults for no apparent reasonpthread_create 无明显原因导致段错误
【发布时间】:2021-08-25 16:43:33
【问题描述】:

我一直在编写一些需要在 C 中进行多线程处理的函数,pthreads 似乎很简单。但是现在我已经写出来了,它一直在给我的段错误,并带有一堆 printf() 语句并注释掉部分代码我发现 pthread_create 导致了这些,任何帮助将不胜感激!据我所见,我将参数传递给 pthread_create 似乎非常好。

代码:

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdbool.h>
typedef unsigned long long ll;
struct opscount{
    ll faddpthread;
    ll fsubpthread;
    ll fmulpthrea;
    ll fdivpthread;
};
int main(){
    int total_thread,time;
    printf("Enter total number of threads : ");
    scanf("%i",&total_thread);
    printf("Time to run the test : ");
    scanf("%i",&time);
    struct opscount opcount[total_thread];
    pthread_t thread[total_thread];
    //---------------------start of fadd test----------------------------------
    for(int i=0;i<total_thread;i++)
    {
        opcount[i].faddpthread=0;
        pthread_create(&thread[i],NULL,faddtf,opcount+i);
    }
    int optime=time/4;
    sleep(optime);
    for(int i=0;i<total_thread;i++)
    {
        pthread_cancel(thread[i]);// kills the threads
    }
}

线程函数是:

void *faddtf(void *oppthread)
{
    double c=0.75665;
    while(true)
    {
        c+=v1+v2+v3+v4+v5;
        ((struct opscount *)oppthread)->faddpthread+=5;
    }
}

【问题讨论】:

  • 好吧,经过一番谷歌搜索后,我发现了这个:linuxquestions.org/questions/linux-newbie-8/… 我认为将 stuct 作为参数传递给 pthread_create 会导致问题,我将其换成了数组,它肯定修复了错误。
  • Re, "...struct as parameter...array..." 这没有意义。唯一可以传递给新线程的是一个指针。只要(a)它指向的东西在线程的生命周期内继续存在,指针指向的东西就无关紧要了。线程,以及 (b) pthread_create(..., my_pointer) 的调用者和线程中运行的代码都同意该事物的大小和类型。

标签: c multithreading pthreads


【解决方案1】:

代码有两个错误。

一个是运行main的线程可以终止,破坏opcount所在的堆栈。这可能发生在线程实际上有机会终止之前。您不必等待它们终止。 (而且它们不会因为第二个错误而终止。)

第二个错误是您尝试取消的线程没有任何方法可以取消。他们不检查是否已被取消。它们不启用异步取消。

可能发生的情况是,当线程在第一个线程终止后访问第一个线程堆栈上的对象并成功时,您的代码会崩溃,如果幸运的是,进程在此之前终止,因为从 main 返回会终止进程。

【讨论】:

  • 所以如果我让主线程等待线程函数,我的两个错误都得到修复了吗?我猜你在这里谈论的是 pthread_join。
  • 那么对pthread_join 的调用将永远不会返回,因为您的线程永远不会终止。他们不支持取消,因此在他们身上调用pthread_cancel 不会做任何事情。它们没有取消点,不支持异步取消,所以没有办法取消。
  • 好的,所以我需要另一个函数,它有一个 return 语句并在 sleep 后返回,即使使用 pthread_join 和 return 函数,我也需要 pthear_cancel 吗?
  • 如果不了解您实际想要做什么,就很难回答。为什么要取消线程?为什么不直接将线程编码为只执行您希望他们执行的工作,这样您就不必“从外部进入”来取消它们?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-29
  • 1970-01-01
  • 2020-11-07
  • 2013-10-14
相关资源
最近更新 更多