2012-10-25 63 views
0

我有一個服務器/客戶端應用程序,有2個不同版本。第一個客戶端讀取文本文件並將文本數據發送到服務器,服務器將接收到的數據寫入新的文本文件(「received.txt」) ,並在完成書寫時,將文本文件打印到屏幕上。如何使用2個線程同時讀取/寫入文件?

在第二個版本中,客戶端執行同樣的操作,但是我希望服務器在寫入文件「received.txt」的同時將數據打印到屏幕上。你可能想知道我爲什麼要做這樣的事情。我想加快寫入文件並將文件打印回屏幕的過程。我想,如果我使用2個線程,我可能會加快工作。

雖然我遇到了一個問題(這是我第一次使用pthreads)。服務器在將數據輸出到屏幕之前終止。我認爲這是關於調度。當新創建的線程正在運行並且主線程被阻塞時,該文件沒有任何可讀的內容,然後新創建的線程終止。這是我對這個問題的猜測。如果可能的話,我想在這裏實現的是同時進行這種讀/寫操作。如果我這樣做都是錯的,或者我不能讓simultenous讀/寫線程寫,讓我知道:)

這裏是服務器(第二版):

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

不要同時讀寫一個文件。使用至少一個互斥體來序列化它。 https://computing.llnl.gov/tutorials/pthreads/ –

+0

嗯,我不知道如何使用互斥體,我現在將谷歌它。 – feluna

回答

2
  1. 使用互斥鎖定「活動寫入部分」
  2. 對文件IO使用複用。請參閱pool或epol,選擇Linux系統調用
+0

好吧,我會學習它們並嘗試。謝謝您的回答。 – feluna

+0

如果你將卡住的東西填補免費張貼在這裏,我可以舉幾個例子(但我需要一些時間來搜索這個例子在我的例子在硬盤(rofl)的「垃圾」) – Maxim

+0

另請參閱http:// advancedlinuxprogramming .com /或http://basepath.com/aup/ –

相關問題