C 如何使用两个线程同时读取/写入文件?

C 如何使用两个线程同时读取/写入文件?,c,file-io,pthreads,C,File Io,Pthreads,我有一个服务器/客户端应用程序,有两个不同的版本。在第一个版本中,客户端读取一个文本文件并向服务器发送文本数据,服务器将接收到的数据写入一个新的文本文件(“received.txt”),当它完成写入后,将文本文件打印到屏幕上 在第二个版本中,客户机执行相同的操作,但我希望服务器在写入文件“received.txt”的同时将数据打印到屏幕上。你可能想知道我为什么要做这样的事。我想加快写入文件并将文件打印回屏幕的过程。我想如果我使用两个线程,可能会加快工作速度 不过,我遇到了一个问题(这是我第一次使

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

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

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

这是服务器(第二个版本):

#包括
#包括
#包括
#包括
#包括
#包括
无效错误(字符*消息){
佩罗尔(味精);
出口(1);
}
//新线程函数
void*printData(){
文件*fp=fopen(“received.txt”、“r”);
字符缓冲区;
time\u t time1=时间(空);
如果(fp!=NULL){
while((buffer=fgetc(fp))!=NULL){
printf(“%c”,缓冲区);
}
fclose(fp);
}
time\u t time2=时间(空);
double diff=difftime(time2,time1);
printf(“耗时%.lf秒。\n”,差异);
pthread_exit(NULL);
}  
int main(int argc,char*argv[]){
int sockfd,newsockfd,端口号,cli长度,n;
字符缓冲区[256];
服务器地址、客户端地址中的结构sockaddr\u;
文件*fp;
int thread_Created=0;
pthread\u t线程;
如果(argc<2){
fprintf(stderr,“错误,没有提供端口!”);
出口(1);
}
sockfd=套接字(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
错误(“打开套接字时出错”);
bzero((char*)和server_addr,sizeof(server_addr));
端口号=atoi(argv[1]);
服务器地址sin家庭=AF网络;
服务器地址sin\u端口=htons(端口号);
server\u addr.sin\u addr.s\u addr=INADDR\u ANY;
if(bind(sockfd,(struct sockaddr*)和server_addr,sizeof(server_addr))<0){
错误(“绑定错误”);
}
听(sockfd,5);
cli_length=sizeof(&client_addr);
newsockfd=accept(sockfd,(struct sockaddr*)&client\u addr,&cli\u length);
if(newsockfd<0)
错误(“接受时出错”);
b0(缓冲器,256);
如果((fp=fopen(“received.txt”,“w”)!=NULL){
而((n=read(newsockfd,buffer,255))!=0){
int i=0;
对于(i=0;i<255;i++){
如果(缓冲区[i]!='\0')
fputc(缓冲区[i],fp);
}
//创建一个新线程来读取文件并打印结果
如果(!创建了线程){
pthread_create(&thread,NULL,printData,NULL);
创建的线程=1;
}
}
}
fclose(fp);
/*while(pthread_kill(thread,0)=0){*/
/* } */
}
  • 使用互斥锁锁定“活动写入部分”
  • 对文件IO使用多路复用。请参阅池或epol,选择Linux系统调用

  • 不要同时读写一个文件。至少使用一个互斥来序列化它。嗯,我不知道如何使用互斥体,我现在就用谷歌搜索。如果你想在这里发布一些免费的东西,我可以举几个例子(但我需要一些时间在我的硬盘(rofl)上的例子的“垃圾”中搜索这些例子)
    #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 ) { */
      /* } */
    }