两个线程进入无限循环

时间:2015-08-20 10:03:05

标签: c++ c multithreading operating-system

我正在学习pthread的概念。我为以下问题编写了一个代码:

  

实现以下模型:创建主线程。它开了一个   文件。在任意间隔,主线程创建工作线程   随机间隔和每个工作线程将随机休眠   在从文件中读取一行并最终退出之前的间隔。

我写了以下代码:

#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;
}

执行时,代码进入无限循环。有时只执行第一行然后它进入无限循环。即使我使用pthread_join,问题仍未解决。 为什么它会进入无限循环?

4 个答案:

答案 0 :(得分:4)

以下是一些问题:

  • 您在c和两个主题中使用了一个全局变量main。所以他们都覆盖了其他人使用的价值。
  • 您有一个几乎完全相同的代码副本:f1()f2()。相反,您可以拥有一个由多个线程运行的函数f()。这是多线程的主要思想。
  • 您可以使用pthread_self()打印主题ID。
  • 从函数返回时,
  • pthread_exit()会被隐式调用。
  • main()未明确地作为线程启动,因此调用pthread_exit()没有意义。
  • 你缺乏沟通和线程之间的同步,告诉对方他们将要读取哪一行。你应该使用'master'线程来跟踪,并让每个'worker'线程询问在哪里阅读。 (这是我所说的非常重要的任务。)

答案 1 :(得分:2)

编辑@Maksim Solovjov后的评论

实际上问题是你只读了一行,即直到'\n'被击中。一旦任何线程读取此'\n'字符,就不会再读取其他线程(或主while循环)。因此它将永远陷入循环。

因此,如果您在以下两个线程中更改while循环,

while(c!=EOF)

线程将继续并读取下一行。最后,流量将达到EOF,线程可以退出。

修改线程后代码看起来像

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);
}

答案 2 :(得分:2)

在第1个线程函数f1中,您正在编写

while(c!='\n'&& c!=EOF)
    {
        printf("1 %c\n",c);
        c=getc(f);
    }

然后你回到主函数和第二个线程。所以现在,c的值是'\n'。因此在f2中,您将不会进入循环。因此,main中的while循环将永远持续,因为c的值不会改变并且卡在'\n'中。这是获得无限循环的原因。因此,您还可以得出结论,您创建的线程没有进入任何无限循环。

解决方案:

一旦退出线程函数中的循环,请更改c。

的值
if(c!=EOF)
   c = getc(f);

答案 3 :(得分:1)

在无限循环中永远不会有两个线程&#34;。它是inifinite循环中的主要线程。发生这种情况是因为: 您正在读取由不同线程调用的两个不同函数中的文件,直到其中一个达到EOF或&#34; \ n&#34;。 假设你的线程执行函数到达&#34; \ n&#34;它会退出。但是现在主线程将进入无限循环,因为EOF永远不会同时检查函数(c!=&#39; \ n&#39;&amp;&amp; c!= EOF)以进一步读取文件。

为了摆脱这种情况,你可以使用一个全局状态变量,它将负责&#34; \ n&#34;阻塞。

代码将如下所示:

#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;
}