我正在使用putty运行以下代码,并且预期的行为应该如下:当负责从文件读取的线程结束时,负责计时器的另一个线程也必须结束并反向:如果线程负责计时器已经结束,另一个也必须结束。但是当我还有一分钟时,我得到了这个致命的错误:Server unexpectedly closed network connection
。我做错了什么?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
/* global variables to check the state*/
int read = 0;
int timeLeft = 0;
void *readFromFile(void *myFile)
{
int state;
char *theFile;
theFile = (char*) myFile;
char question[100];
char answer[100];
state = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL );
FILE *file = fopen(theFile, "r");
if (file != NULL )
{
while (fgets(question, sizeof question, file) != NULL )
{
fputs(question, stdout);
scanf("%s", &answer);
}
fclose(file);
state = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL );
printf("Done with questions!\n");
read = 1;
}
else
{
perror(theFile);
}
}
void displayTimeLeft(void *arg)
{
int *time;
int state;
time = (int*) arg;
int i;
state = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL );
for (i = time; i >= 0; i -= 60)
{
if (i / 60 != 0)
{
printf("You have %d %s left.\n", i / 60,
(i / 60 > 1) ? "minutes" : "minute");
sleep(60);
}
else
{
state = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL );
printf("The time is over \n");
timeLeft = 1;
break;
}
}
}
int main()
{
pthread_t thread1;
pthread_t thread2;
char *file = "/home/osystems01/laura/test";
int *time = 180;
int ret1;
int ret2;
ret1 = pthread_create(&thread1, NULL, readFromFile, file);
ret2 = pthread_create(&thread2, NULL, displayTimeLeft, time);
printf("Main function after pthread_create\n");
while (1)
{
if (read == 1)
{
pthread_cancel(thread2);
pthread_cancel(thread1);
break;
}
else if (timeLeft == 1)
{
pthread_cancel(thread1);
pthread_cancel(thread2);
break;
}
}
printf("After the while loop!\n");
return 0;
}
答案 0 :(得分:0)
这里是初始化指向内存位置180的指针。
int *time = 180;
我们需要的是:
int time = 180;
...
...
ret2 = pthread_create(&thread2, NULL, displayTimeLeft, &time);
答案 1 :(得分:0)
正如我在评论中提到的,我强烈怀疑服务器会关闭通过putty建立的连接,因为您的程序存在问题。
但是这个程序的代码有几个问题。
ost关键问题是你是从两个线程同时访问两个全局变量。
需要保护并发访问。为此,请声明两个互斥量:
pthread_mutex_t mutex_read = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_time = PTHREAD_MUTEX_INITIALIZER;
void *readFromFile(void *myFile)
{
...
{
int result = pthread_mutex_lock(mutex_read);
if (0 != result)
{
perror("pthread_mutex_lock(mutex_read) failed");
}
}
read = 1;
{
int result = pthread_mutex_unlock(mutex_read);
if (0 != result)
{
perror("pthread_mutex_unlock(mutex_read) failed");
}
}
...
}
void displayTimeLeft(void *arg)
{
...
{
int result = pthread_mutex_lock(mutex_time);
if (0 != result)
{
perror("pthread_mutex_lock(mutex_time) failed");
}
}
timeLeft= 1;
{
int result = pthread_mutex_unlock(mutex_time);
if (0 != result)
{
perror("pthread_mutex_unlock(mutex_time) failed");
}
}
...
}
int main(void)
{
...
while(1)
{
int bread = 0;
int btimeLeft = 0;
{
int result = pthread_mutex_lock(mutex_read);
if (0 != result)
{
perror("pthread_mutex_lock() failed");
}
}
bread = (1 == read);
{
int result = pthread_mutex_unlock(mutex_read);
if (0 != result)
{
perror("pthread_mutex_unlock() failed");
}
}
{
int result = pthread_mutex_lock(mutex_time);
if (0 != result)
{
perror("pthread_mutex_lock() failed");
}
}
btimeLeft = (1 == timeLEft);
{
int result = pthread_mutex_unlock(mutex_time);
if (0 != result)
{
perror("pthread_mutex_unlock() failed");
}
}
if (bread == 1)
{
pthread_cancel(thread2);
pthread_cancel(thread1);
break;
}
else if (btimeLeft == 1)
{
pthread_cancel(thread1);
pthread_cancel(thread2);
break;
}
}
...
对于PThreads,thr threas函数需要声明为:
void * (*) (void *)
displayTimeLeft
在“字符串”中扫描时,需要传递表示字符串的字符数组的第一个元素的地址。所以这个
scanf("%s", &answer);
应该是这个
scanf("%s", &answer[0]);
或者
scanf("%s", answer);
代码错过了sleep()
的原型,所以添加
#include <unistd.h>
完成此操作后,编译器会检测到系统调用read()
与您的代码声明的全局变量read
之间的名称冲突。这不好。将read
重命名为readit
。
最后,至少在他的回答中有 suspectus 的问题。您滥用指向int
的指针来存储一些时间值(int * time = 180
)。不要那样做。
要解决此问题,请执行以下操作:
int main(void)
{
...
int time = 180;
...
ret2 = pthread_create(&thread2, NULL, displayTimeLeft, &time);
并在displayTimeLeft
中执行:
int time = *((int*) arg);