服务器意外关闭了网络连接

时间:2013-11-10 12:53:45

标签: c linux multithreading pthreads

我正在使用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;
}

2 个答案:

答案 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);