1

パテを使用して次のコードを実行していますが、予想される動作は次のようになります。ファイルからの読み取りを担当するスレッドが終了すると、タイマーを担当する他のスレッドも終了して逆にする必要があります。タイマーが終了したため、もう一方のタイマーも終了する必要があります。しかし、私はこの致命的なエラーを受け取ります:Server unexpectedly closed network connection残り 1 分です。私は何を間違っていますか?

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

2 に答える 2

0

私のコメントで述べたように、プログラムに問題があるため、サーバーがパテ経由で確立された接続をシャットダウンすることを強く疑っています。

ただし、プログラムのコードにはいくつかの問題があります。


最も重要な問題は、2 つのスレッドから同時に 2 つのグローバル変数にアクセスしていることです。

同時アクセスは保護する必要があります。そのためには、次のように 2 つのミューテックスを宣言します。

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


最後に、彼の回答で容疑者が言及している問題があります。へのポインターを誤って使用して、int時間値を格納しています ( int * time = 180)。そんなことしたらダメ。

これを修正するには、次のようにします。

int main(void)
{
  ...
  int time = 180;
  ...
  ret2 = pthread_create(&thread2, NULL, displayTimeLeft, &time);

そしてdisplayTimeLeft行う:

 int time = *((int*) arg);
于 2013-11-10T14:42:20.293 に答える
0

ここでは、メモリ位置 180 へのポインタを初期化しています。

int *time = 180;

必要なものは次のとおりです。

int time = 180;
...
...
ret2 = pthread_create(&thread2, NULL, displayTimeLeft, &time);
于 2013-11-10T13:01:16.820 に答える