Reputation:
I am learning the concept of pthread. I wrote a code for the following question :
Implement the following model: Create a master thread. It opens a file. At random intervals, the master thread creates worker threads at random intervals and each worker thread will sleep for random intervals before it reads a line from the file and finally exits.
I wrote the following code :
#include<stdio.h>
#include<pthread.h>
char c;
void *f1(void *f)
{
printf("Calling from thread 1\n");
sleep(rand()%2);
while(c!='\n'&& c!=EOF)
{
printf("1 %c\n",c);
c=getc(f);
}
pthread_exit(NULL);
}
void *f2(void *f)
{
printf("Calling from thread 2\n");
sleep(rand()%2);
while(c!='\n' && c!=EOF)
{
printf("2 %c\n",c);
c=getc(f);
}
pthread_exit(NULL);
}
int main()
{
pthread_t tid1,tid2;
FILE *f;
f=fopen("new.txt","r");
int i;
c=getc(f);
while(c!=EOF)
{
i=rand()%2;
sleep(i);
pthread_create(&tid1,NULL,f1,(void *)f);
i=rand()%2;
sleep(i);
pthread_create(&tid2,NULL,f2,(void *)f);
}
pthread_exit(NULL);
return 0;
}
While executing, the code enters an infinite loop. Sometimes only the first line is being executed then it enters an infinite loop. Even when I used pthread_join
, the problem was not solved.
Why is it entering an infinite loop?
Upvotes: 3
Views: 2105
Reputation: 488
In the 1st thread function f1, you are writing
while(c!='\n'&& c!=EOF)
{
printf("1 %c\n",c);
c=getc(f);
}
Then you get back to the main function and to the second thread. So right now, the value of c is '\n'
. Thus in f2, you will not enter the loop. Hence, the while loop in main will continue forever since the value of c is not changing and is stuck in '\n'
. This is reason for getting the infinite loop. So, you can also conclude that the threads that you created are not entering in any infinite loop.
Solution :
As soon as you exit the loop in the thread functions, change the value of c.
if(c!=EOF)
c = getc(f);
Upvotes: 1
Reputation: 21
There are never "two threads in infinite loop". Its the main thread which is in inifinite loop. This is happening because: You are reading file in two different functions called by different threads till either of one reach EOF or "\n". Say your thread executing function one reaches "\n" it will quit. But now main thread will go in inifinite loop because EOF will never come as both function checking for while(c!='\n'&& c!=EOF) to further read file.
For coming out of this situation, you can use one global state variable, which will take care of "\n" blocking.
Code will be look like this:
#include<stdio.h>
#include<pthread.h>
char c;
int isBlock;
void *f1(void *f)
{
printf("Calling from thread 1\n");
sleep(rand()%2);
while((c!='\n' || isBlock) && c!=EOF)
{
isBlock = 0;
printf("1 %c\n",c);
c=getc(f);
}
isBlock = 1;
printf("exiting from thread 1\n");
pthread_exit(NULL);
}
void *f2(void *f)
{
printf("Calling from thread 2\n");
sleep(rand()%2);
while((c!='\n'|| isBlock) && c!=EOF)
{
isBlock = 0;
printf("2 %c\n",c);
c=getc(f);
}
isBlock = 1;
printf("exiting from thread 2\n");
pthread_exit(NULL);
}
int main()
{
pthread_t tid1,tid2;
FILE *f;
f=fopen("checkConnection.cpp","r");
int i;
c=getc(f);
isBlock = 0;
while(c!=EOF)
{
//c=getc(f);
i=rand()%2;
sleep(i);
pthread_create(&tid1,NULL,f1,(void *)f);
i=rand()%2;
sleep(i);
pthread_create(&tid2,NULL,f2,(void *)f);
}
pthread_exit(NULL);
return 0;
}
Upvotes: 1
Reputation: 1605
EDIT AFTER @Maksim Solovjov COMMENT
Actually the issue is you are reading only a line is read i.e. till '\n'
is hit. Once any of the thread reads this '\n'
character, no other thread (or main while-loop) will read further. And thus it'll stuck in loop forever.
So, if you change the while loop in both the thread as below,
while(c!=EOF)
threads will go ahead and read next line. Finally the flow will reach EOF and thread can exit.
After modifying your threads code will look like
void *f1(void *f)
{
printf("Calling from thread 1\n");
sleep(rand()%2);
while( c!=EOF) //======>>>this is where change is required.
{
printf("1 %c\n",c);
c=getc((FILE *)f);
}
pthread_exit(NULL);
}
Upvotes: 2
Reputation: 22946
Here are some issues:
c
in main
and both threads. So they are all overwriting the value used by the others.f1()
and f2()
. Instead you can have one function f()
that you run by multiple threads. This is a main idea of multi-threading.pthread_self()
.pthread_exit()
is called implicitly when you return from a function.main()
was not started as a thread explicitly, so calling pthread_exit()
does not make sense.Upvotes: 4