为什么我的简单pthreads程序会因为分段错误而崩溃?

时间:2017-01-18 05:37:58

标签: c linux pthreads

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include<signal.h>
#include<unistd.h>//getch();
#include <termios.h>//getch();
#include <pthread.h>
volatile sig_atomic_t flag = 0;

char getch()
{
  int buf=0;
  struct termios old= {0};
  fflush(stdout);
  if(tcgetattr(0, &old)<0)
    perror("tcsetattr()");
  old.c_lflag&=~ICANON;
  old.c_lflag&=~ECHO;
  old.c_cc[VMIN]=1;
  old.c_cc[VTIME]=0;
  if(tcsetattr(0, TCSANOW, &old)<0)
    perror("tcsetattr ICANON");
  if(read(0,&buf,1)<0)
    perror("read()");
  old.c_lflag|=ICANON;
  old.c_lflag|=ECHO;
  if(tcsetattr(0, TCSADRAIN, &old)<0)
    perror ("tcsetattr ~ICANON");
  //printf("%c\n",buf);//to print the value typed.
  return buf;
}

void *send_function()
{
  printf("\n Send Thread \n");
  //return 0;
}

void my_function(int sig)
{ // can be called asynchronously
  flag = 1; // set flag
}

int main ()
{
  char selection;//user input(s or r)
  pthread_t send;
  while(1)
  {  
    signal(SIGINT, my_function);
    //printf("\n Before SIGINT \n");            
    if(flag)
    { 
        printf("\n Choose your terminal S or R \n");
        selection=getch();
        flag = 0;
    }   
    if(selection=='s')
        if(pthread_create(&send,NULL,send_function(),NULL))
        {
        fprintf(stderr, "Error creating thread\n");
        return 1;
        }
    else if(selection=='r')
        printf("Receive Function is received");
    //printf("\n After SIGINT \n"); 
 }
  return 0;  

} 

输出:

 nivas@balakrishnan-HCL-Desktop:~/C_sample$ gcc -pthread -o thread thread.c

 nivas@balakrishnan-HCL-Desktop:~/C_sample$ ./thread

 Choose your terminal S or R

 Send Thread

 Send Thread

 Send Thread

 Send Thread

 Send Thread
 Segmentation fault (core dumped)
 nivas@balakrishnan-HCL-Desktop:~/C_sample$ ^C
 nivas@balakrishnan-HCL-Desktop:~/C_sample$

在上面的程序中,我遇到了分段错误。按下"Send Thread"后,我所需的输出是连续打印's'。我已经调查了以前类似的问题,但我找不到答案。任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

这一行:

if(pthread_create(&send,NULL,send_function(),NULL))

错字? pthread_create的第三个参数是一个函数指针,线程应该从这里开始。

应该是:

if(pthread_create(&send,NULL,send_function,NULL))

此外,您创建的线程不会真正退出,除非您将其属性位设置为分离,或明确分离它们,或使用pthread_join收集状态。

答案 1 :(得分:0)

您需要更改功能send_function()According to the man page,此函数应该将void指针作为参数,并且应该返回指向void的指针:

void * send_function(void *parg)
{
  printf("\n Send Thread \n");
  return parg;
}

您还需要更正函数调用,其中包括一对迷路括号:

if(pthread_create(&send,NULL,send_function,NULL)) {}

实际上,您的程序将循环打印"Send Thread",直到系统资源耗尽。您可以通过在main()中的循环之前添加这些行来创建在终止时释放系统资源的分离线程:

pthread_attr_t attr;

if (pthread_attr_init(&attr) != 0) {
    perror("Error in pthread_attr_init()");
    exit(EXIT_FAILURE);
}

if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) {
    perror("Error in pthread_attr_setdetachstate()");
    exit(EXIT_FAILURE);        
}

然后将循环内的pthread_create()调用更改为:

if(pthread_create(&send, &attr, send_function, NULL)) {}

更改后,您的程序应重复打印"Send Thread",在打印每封邮件后释放资源,直到您停止。