两个线程进入无限循环
Two threads entering in infinite loops
我正在学习pthread概念。我为下面的问题写了一个代码:
实现以下模型:创建一个主线程。它打开一个文件。以随机的间隔,主线程创建工作线程随机间隔和每个工作线程将随机休眠从文件中读取一行并最终退出的时间间隔。
我写了以下代码:
#include<stdio.h>
#include<pthread.h>
char c;
void *f1(void *f)
{
printf("Calling from thread 1n");
sleep(rand()%2);
while(c!='n'&& c!=EOF)
{
printf("1 %cn",c);
c=getc(f);
}
pthread_exit(NULL);
}
void *f2(void *f)
{
printf("Calling from thread 2n");
sleep(rand()%2);
while(c!='n' && c!=EOF)
{
printf("2 %cn",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
时,问题也没有解决。为什么会进入无限循环?
以下是一些问题:
- 你在
main
和两个线程中使用一个全局变量c
。所以它们都覆盖了其他使用的值。 - 您有一个几乎完全相同的代码副本作为线程运行:
f1()
和f2()
。相反,您可以使用一个由多个线程运行的函数f()
。这是多线程的主要思想。 - 可以使用
pthread_self()
打印线程ID。 -
pthread_exit()
在函数返回时隐式调用。 -
main()
没有作为线程显式启动,所以调用pthread_exit()
没有意义。 - 你缺乏沟通&线程之间的同步,告诉对方它们将读取哪一行。你应该使用"主"线程来跟踪,并让每个"工作"线程询问读取的位置。(我想说这是一个不平凡的任务。)
EDIT AFTER @Maksim Solovjov COMMENT
实际上问题是你只读一行,即直到'n'
被击中。一旦任何线程读取了这个'n'
字符,其他线程(或主while-loop)就不会再读取了。因此,它将永远卡在循环中。
那么,如果你像下面这样改变两个线程中的while循环,
while(c!=EOF)
线程将继续读取下一行。最后,流将到达EOF,线程可以退出。
修改后的线程代码将看起来像
void *f1(void *f)
{
printf("Calling from thread 1n");
sleep(rand()%2);
while( c!=EOF) //======>>>this is where change is required.
{
printf("1 %cn",c);
c=getc((FILE *)f);
}
pthread_exit(NULL);
}
在第一个线程函数f1中,您正在编写
while(c!='n'&& c!=EOF)
{
printf("1 %cn",c);
c=getc(f);
}
然后返回到主函数和第二个线程。现在,c的值是'n'
。因此在f2中,您将不会进入循环。因此,main中的while循环将永远继续下去,因为c的值没有改变,并且卡在'n'
中。这就是产生无限循环的原因。因此,您还可以得出结论,您创建的线程没有进入任何无限循环。
解决方案:
一旦退出线程函数中的循环,就更改c的值。
if(c!=EOF)
c = getc(f);
永远不会有"无限循环中的两个线程"。它是处于无限循环中的主线程。这是因为:你在两个不同线程调用的不同函数中读取文件,直到其中一个到达EOF或"n"。假设你的线程执行函数1达到"n",它将退出。但是现在主线程将进入无限循环,因为EOF将永远不会出现在两个函数检查while(c!='n'&&c!=EOF)进一步读取文件。
为了摆脱这种情况,您可以使用一个全局状态变量,它将处理"n"阻塞。
代码看起来像这样:
#include<stdio.h>
#include<pthread.h>
char c;
int isBlock;
void *f1(void *f)
{
printf("Calling from thread 1n");
sleep(rand()%2);
while((c!='n' || isBlock) && c!=EOF)
{
isBlock = 0;
printf("1 %cn",c);
c=getc(f);
}
isBlock = 1;
printf("exiting from thread 1n");
pthread_exit(NULL);
}
void *f2(void *f)
{
printf("Calling from thread 2n");
sleep(rand()%2);
while((c!='n'|| isBlock) && c!=EOF)
{
isBlock = 0;
printf("2 %cn",c);
c=getc(f);
}
isBlock = 1;
printf("exiting from thread 2n");
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;
}
- 为什么我不能在 while 循环中创建线程?
- Qt 在另一个线程中无限循环
- 如何在无限循环中启动和停止(切换)多个线程
- 更好的做法:永远循环线程或连续线程
- Qt的事件循环线程是安全的还是原子的?处理"队列连接"时如何同步?
- 停止不同线程中的无限循环
- 在调试线程时无限循环
- 线程:C++ 中无限循环线程的终止
- main 终止具有无限循环的线程
- C++线程&无限循环
- 无限循环多线程
- 英特尔 TBB 并行循环线程 ID
- 在Qt中,当事件循环线程拥有的QObject上的插槽正在执行时,QThread的事件循环是否会阻塞?
- 终止一个在无限循环中运行的std::线程
- 使用两个线程运行和中断一个无限循环
- 为什么我得到无限循环只有线程# 0后,所有5个线程运行多线程c++用餐哲学家谜语
- 两个线程进入无限循环
- 高频循环/线程定时
- 当循环/线程断点发生时
- 如何在无限循环中运行线程