Link to home
Start Free TrialLog in
Avatar of dwiseman3
dwiseman3Flag for Afghanistan

asked on

fgets or pthread causing a segmentation fault

I get a segmentation fault when I run this program. "Producer created" appears on the screen. After I type in a character a  "Segmentation fault occurs. If I don't enter data the "Consumer created" appears and I still get a segmentation fault. I'm just trying to get thread one to read  the stdin data and thread 2 to write the data to stdout. I'm not that familiar with pthread_create, how it shares data, or all these pointers. I know something is overflowing in memory but I don't know how to fix the problem.
It may be that fgets and fputs that are causing problems too. Can someone please help me with this program? Thanks

#include <pthread.h>
#include <stdio.h>
void *Producer(void *data);
void *Consumer(void *data);

int main()
 {
  pthread_t t1, t2;
 
  printf("main started\n");
  pthread_create(&t1, NULL, Producer, NULL);
  sleep(3);
  pthread_create(&t2, NULL, Consumer, NULL);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  printf("main done \n");
}
                                                                       
void *Producer(void *data)
{   int i=0;
   
      printf("Producer created\n");
      for(i;i=1;i++)
           {
                  sleep(3);
            fgets(data,27,stdin);
                  printf("data read \n");
                  sleep(3);
           }    
}

void *Consumer(void *data)
 {
  int i=0;
  printf("Consumer created\n");
  for (i ; i= 1; i++)      
  fputs(data,stdout);
 
}
Avatar of nixfreak
nixfreak

> for(i;i=1;i++)

for(i; i == 1; i++)
Avatar of dwiseman3

ASKER

Thanks for your quick response...it's always those little things that cause problems. Still, after that fix, I don't think I'm passing anything from stdin to data. The Producer function doesn't printf("data read \n"). Consumer created is printed but no input goes to stdout. If I change the for loop in Producer to while(1) the segmentation fault returns.
Is fgets the problem?
To be honest I don't know much about threads :)
But when I corrected both the for loops for the error then the program seems to work fine. I am wondering where "data" is getting stored?
Avatar of jkr
You are passing NULL as data and then use

            fgets(data,27,stdin);

That for sure will cause a segfault, since it is equivalent to

            fgets(NULL,27,stdin);

Try passing a valid buffer, i.e.

int main()
 {
  pthread_t t1, t2;
  char in[28];
  char out[28];
 
  printf("main started\n");
  pthread_create(&t1, NULL, Producer, (void*) out);
  sleep(3);
  pthread_create(&t2, NULL, Consumer, (void*) in);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  printf("main done \n");
}
That helped, but stdin and stdout are not getting my input. When I run this code:

#include <pthread.h>
#include <stdio.h>
void *Producer(void *data);
void *Consumer(void *data);

int main()
 {
  pthread_t t1, t2;
  char in[28];
  char out[28];
  printf("main started\n");
  pthread_create(&t1, NULL, Producer,(void*) in);
  sleep(3);
  pthread_create(&t2, NULL, Consumer, (void*)out);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  printf("main done \n");
}
                                                                           
void *Producer(void *data)
{   int i=0;
   
      printf("Producer created\n");
      for(i;i==1;i++)
           {
                  sleep(3);
            fgets(data,27,stdin);
                  printf("data read \n");
                  sleep(3);
           }    
}

void *Consumer(void *data)
 {
  int i=0;
  printf("Consumer created\n");
  for (i;i==1;i++)      
  {
        fputs(data,stdout);
        printf("data out \n");
  }  
  return NULL;
}

The results are:

main started
Producer created
abc
Consumer created
main done
[dwiseman@06 ~/project]$ abc
The loop conditions are bogus. I is assigned a 0 the loop executed only when 'i==1' - IOW never. Make that

      for(i = 0;i<1;i++)
           {
                  sleep(3);
            fgets(data,27,stdin);
                  printf("data read \n");
                  sleep(3);
           }    
Just a suggestion, shouldn't you use a single data pointer instead of "in" and "out"
....
  char *data;

  printf("main started\n");
  pthread_create(&t1, NULL, Producer,(void*) data);
  sleep(3);
  pthread_create(&t2, NULL, Consumer,(void*) data);
.....
I'd take that as a next step when the whole thing works ;o)
I removed the loop as suggested by JKR and the program now works fine.

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *Producer(void *data);
void *Consumer(void *data);

int main()
 {
  pthread_t t1, t2;
  char *data;

  printf("main started\n");
  pthread_create(&t1, NULL, Producer, data);
  sleep(3);
  pthread_create(&t2, NULL, Consumer, data);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  printf("main done \n");
}

void *Producer(void *data)
{
      printf("Producer created\n");
      fgets(data,27,stdin);
      printf("data read \n");
}

void *Consumer(void *data)
{
        printf("Consumer created\n");
        fputs(data,stdout);
}
I fixed the for loops...the program flows like it should. Still, I got no stdin or stdout. So, I changed the function arguments from in/out to data....back to a Segmentation fault problem.

#include <pthread.h>
#include <stdio.h>
int main()
 {
  pthread_t t1, t2;
  void *Producer(void *data);
  void *Consumer(void *data);
  char in[28];
  char out[28];
  char *data;
  printf("main started\n");
  pthread_create(&t1, NULL, Producer,(void*)data);
  sleep(3);
  pthread_create(&t2, NULL, Consumer, (void*)data);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  printf("main done \n");
}
                                                                             
void *Producer(void *data)
{   int i;
    printf("Producer created\n");
      for(i=0;i<1;i++)
           {
                  sleep(3);
            fgets(data,27,stdin);
                  printf("data read \n");
                  sleep(3);
           }    
}
void *Consumer(void *data)
{
  int i;
  printf("Consumer created\n");
  for (i=0;i<1;i++)      
  {
        fputs(data,stdout);
        printf("data out \n");
  }  
  return NULL;
}

RESULTS:
main started
Producer created
abc
Segmentation fault

ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
by golly it worked!! I just have to put some locks on it or increase the sleep.
Thank you very much!
Yup, was just about to mention the locks. See also http://www.llnl.gov/computing/tutorials/pthreads/#Mutexes