c - 如何用2个线程同时读取/写入文件?

标签 c file-io pthreads

我有一个服务器/客户端应用程序,有两个不同的版本。在第一个版本中,客户端读取文本文件并将文本数据发送到服务器,服务器将接收到的数据写入新的文本文件(“received.txt” ),当它完成写入时,它将文本文件打印到屏幕上。

在第二个版本中,客户端执行相同的操作,但我希望服务器在写入文件“received.txt”的同时将数据打印到屏幕上。你可能想知道我为什么要做这样的事情。我想加快写入文件并将文件打印回屏幕的过程。我想如果我使用 2 个线程,我可能会加快工作速度。

我遇到了一个问题,(这是我第一次使用pthreads)。服务器在将数据打印到屏幕之前终止。我认为这是关于调度的。当新创建的线程正在运行且主线程被阻塞时,文件没有任何内容可读取,然后新创建的线程终止。这就是我对这个问题的猜测。我想在这里实现的是,如果可能的话,同时进行读/写。如果我做错了,或者我无法使用线程同时读/写,请告诉我:)

这是服务器(第二版):

#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 ) { */
  /* } */
}

最佳答案

  1. 使用互斥体锁定“事件写入部分”
  2. 对文件 IO 使用多路复用。查看池或 epol,选择 Linux 系统调用

关于c - 如何用2个线程同时读取/写入文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13076363/

相关文章:

我可以为了分析目的人为地减慢 C trig 函数吗?

c# - 在文件中搜索字节序列 (C#)

c# - 我可以检查某个文件是否存在于 URL 中吗?

java - 从文件中读取并分割行

c - 奇怪的 C 程序行为

pthreads - 需要互斥锁来保护条件变量

c - 使用 pthread_create 时如何判断是什么导致了段错误?

c - 打印此图案背后的逻辑

c - 如何将行号转换为字节偏移量?

c - 打印 C 中 int 数组的所有递减组合