1

I am using pthread_create to create a thread that examines the amount of lines in a file, then returns the answer to the main thread. I have tried using pthread_join, and malloc() but I am new to both and must have used them improperly. If anyone knows how to pass an integer from a thread back to the main, please help. My code is below.

#include <pthread.h>
#include <stdio.h>

void *count_lines(void *arg)
{
   FILE *fh= (FILE *) arg;

   int num_lines=0;
   char ch;
   for(ch=getc(fh); ch!=EOF; ch=getc(fh))
      if(ch=='\n')
         num_lines=num_lines+1;
   fclose(fh);
   int* value = (int *)malloc(sizeof(int));
   *value=10;
   pthread_exit(value);
}

int main()
{

   FILE *fh;
   fh=fopen("data.txt", "r");

   pthread_t my_thread;
   pthread_create(&my_thread, NULL, count_lines, &fh);

   void *retval;
   pthread_join(my_thread, &retval);
   int i = *((int *)retval);
   free(retval);
   printf("%d\n", i);
}

I am running an Ubuntu virtual machine and using Visual Studio Code if that is of any help. When I run the code above I get a "Core Dump (Segmentation Fault)" error. Again, an help is much appreciated.

Useless
  • 64,155
  • 6
  • 88
  • 132
Alt
  • 21
  • 3
  • The compiler should dump warnings, don't ignore them. – 273K Sep 18 '20 at 07:48
  • `printf` and `getc` are C functions, but you include the C++ header ``. You should ock one language, instead of mixing 2. It's sheer coincidence that this even compilers. – MSalters Sep 18 '20 at 08:00
  • Visual studio code isn't working with pthread so I have to use terminal and terminal throws no warning – Alt Sep 18 '20 at 08:04
  • Do you use C or C++? Please do not use both tags when you do not ask about differences, similarities, how to create code to work in both or something like that. – 12431234123412341234123 Sep 18 '20 at 08:11
  • @MSalters `printf()` and `getc()` are also C++ functions. I am not saying they should be used in C++ but it is valid and well defined to use them when done correctly. – 12431234123412341234123 Sep 18 '20 at 08:12
  • Yes, but in that case they should be included from ``. I just removed the C++ tag and `` since it didn't seem at all relevant. – Useless Sep 18 '20 at 08:24
  • @MSalters, Re, "printf and getc..." The issue is not that they are implemented in C or, that they are imported from the C standard library. The issue is that it's unwise to use functions imported from two different libraries to do the same thing. E.g., mixing C standard library file I/O and C++ standard library file I/O in the same program. – Solomon Slow Sep 18 '20 at 13:13
  • @Alt, Perhaps you are learning something from this exercise, but be aware that it never makes sense for any real program to join a thread immediately after creating the thread without doing any interesting thing in between. The whole point of threads is to allow two different things to happen concurrently, but your `main()` function does not do anything concurrently with the thread that it launches: It just waits for a result. – Solomon Slow Sep 18 '20 at 13:17

2 Answers2

1

You are making everything needlessly complicated. Make a struct such as this:

typedef struct
{
  FILE* fp;
  int   ret_val;
} count_lines_type;

static count_lines_type cl;
cl.fp = fopen (...);
...
pthread_create(&my_thread, NULL, count_lines, &cl);

Fill in ret_val before the thread is done.

I made the struct instance static just in case the calling thread would go out of scope before the count lines thread is done. If it never does that, static isn't necessary.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

Before you create a thread, check if the file is really opened:

fh=fopen("data.txt", "r");
if (fh == NULL) exit(1);

Also fh is already a pointer. You dont need to pass &fh (pointer to pointer) to thred create (you're expecting FILE* not FILE** in count_lines). Also check if thread creation succeeded:

 if (pthread_create(&my_thread, NULL, count_lines, fh) != 0)
    exit(2);  //error -> contents of my_thread is undefined in this case

Also check the retval (dereference only if valid pointer, otherwise segmentation error):

if (retval != NULL)
{
   int i = *((int *)retval);
   free(retval);
}
StPiere
  • 4,113
  • 15
  • 24
  • The file is opened, I think something is happening with the malloc() but I don't know what – Alt Sep 18 '20 at 08:01