user5070412
user5070412

Reputation:

Two threads entering in infinite loops

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

Answers (4)

Richa Tibrewal
Richa Tibrewal

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

linux user
linux user

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

Pawan
Pawan

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

meaning-matters
meaning-matters

Reputation: 22946

Here are some issues:

  • Your using one global variable c in main and both threads. So they are all overwriting the value used by the others.
  • You have an almost exact copy of the code run as thread: f1() and f2(). Instead you can have one function f() that you run by multiple threads. This is a main idea of multi-threading.
  • You can print the thread ID using 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.
  • You're lacking communication & synchronisation between the threads, telling each other which line they'll be reading. You should use the 'master' thread to keep track, and let each 'worker' thread ask where to read. (This is a non-trivial assignment I'd say.)

Upvotes: 4

Related Questions