0

サーバー/クライアント アプリケーションがあり、2 つの異なるバージョンがあります。最初の 1 つのクライアントでは、テキスト ファイルを読み取り、テキスト データをサーバーに送信し、サーバーは受信したデータを新しいテキスト ファイル ("received.txt") に書き込みます。書き込みが完了すると、テキスト ファイルが画面に出力されます。

2番目のバージョンでは、クライアントは同じことを行いますが、サーバーがファイル「received.txt」に書き込むと同時にデータを画面に出力するようにします。なぜ私がそのようなことをしているのだろうと思うかもしれません。ファイルに書き込み、ファイルを画面に出力するプロセスを高速化したいと考えています。2つのスレッドを使用すると、作業がスピードアップするかもしれないと思いました。

ただし、問題が発生しました(pthreadsを使用するのはこれが初めてです)。サーバーは、データを画面に出力する前に終了します。スケジューリングに関するものだと思います。新しく作成されたスレッドが実行され、メイン スレッドがブロックされている間、ファイルには読み取るものがなく、新しく作成されたスレッドは終了します。それが問題についての私の推測です。ここで達成したいのは、可能であれば、これを同時に読み書きできるようにすることです。私がこれをすべて間違っている場合、またはスレッドで同時読み取り/書き込みを行うことができない場合は、お知らせください:)

これがサーバーです(2番目のバージョン):

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include <time.h>

void error(char *msg) {
  perror(msg);
  exit(1);
}

//New Thread function
void *printData() {
  FILE *fp = fopen("received.txt" , "r");
  char buffer;

  time_t time1 = time(NULL);

  if( fp != NULL ) {
    while( ( buffer = fgetc(fp)) != NULL ) {
      printf("%c" , buffer);
    }
    fclose(fp);
  }

  time_t time2 = time(NULL);
  double diff = difftime(time2 , time1);
  printf("It took %.lf seconds.\n" , diff);
  pthread_exit(NULL);
}  

int main(int argc , char *argv[]) {
  int sockfd , newsockfd , port_no , cli_length , n; 
  char buffer[256];
  struct sockaddr_in server_addr , client_addr;
  FILE *fp;

  int thread_Created = 0;
  pthread_t thread;

  if(argc < 2) {
    fprintf(stderr , "ERROR , no port provided!");
    exit(1);
  }

  sockfd = socket(AF_INET , SOCK_STREAM , 0);

  if( sockfd < 0 )
    error("ERROR opening socket.");

  bzero( (char *) &server_addr , sizeof(server_addr) );
  port_no = atoi(argv[1]);

  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons( port_no );       
  server_addr.sin_addr.s_addr = INADDR_ANY;

  if( bind( sockfd , (struct sockaddr *) &server_addr , sizeof(server_addr)) < 0 ) {
    error("ERROR on binding.");
  }

  listen(sockfd , 5);

  cli_length = sizeof(&client_addr);
  newsockfd = accept( sockfd , (struct sockaddr *) &client_addr , &cli_length );
  if (newsockfd < 0 )
    error("ERROR on accept.");

  bzero(buffer , 256);

  if( (fp = fopen("received.txt" , "w")) != NULL ) {
    while( (n = read(newsockfd , buffer , 255)) != 0 ) {

      int i = 0;
      for(i = 0 ; i < 255 ; i++) {
        if( buffer[i] != '\0')
          fputc(buffer[i] , fp);
      }

      //Create a new thread to read the file and print the results
      if( !thread_Created ) {
        pthread_create( &thread , NULL , printData , NULL );
        thread_Created = 1;
      }

    }
  }

  fclose(fp);

  /* while(pthread_kill(thread , 0 ) == 0 ) { */
  /* } */
}
4

1 に答える 1

2
  1. ミューテックスを使用して「アクティブな書き込みセクション」をロックする
  2. ファイル IO に多重化を使用します。プールまたは epol を参照し、Linux システム コールを選択します
于 2012-10-25T20:08:48.117 に答える