2013-09-05 359 views
0

我想檢查ips列表(如果它們被列入黑名單)(使用多線程)。使用多線程讀取文件

所以,我有以下代碼:

pthread_mutex_t input_queue; 

void * process(void * data) 
{ 
    unsigned long ip = 0xffffffff; 
    char line[20]; 
    while (!feof(INFILE)) 
    { 
     pthread_mutex_lock(&input_queue);//?required 
     if (fgets(line,sizeof(line),INFILE) != NULL) 
     { 
      if (strlen(line) < 8) 
       break; 
      if (line[strlen (line) - 1] == '\n') 
       line[strlen (line) - 1] = '\0'; 
      ip = ntohl((unsigned long)inet_addr(line)); 
     } 
     pthread_mutex_unlock(&input_queue); 
     blacklist(ip); 
    } 
    return NULL; 
} 

//in main() 
    pthread_mutex_init(&input_queue,NULL); 
    for(i = 0 ; i < number_thread; i++) 
    { 
     if(pthread_create(&thread_id[i],NULL,&process,NULL) != 0) 
     { 
      i--; 
      fprintf(stderr,RED "\nError in creating thread\n" NONE); 
     } 
    } 
    for(i = 0 ; i < number_thread; i++) 
     if(pthread_join(thread_id[i],NULL) != 0) 
     { 
      fprintf(stderr,RED "\nError in joining thread\n" NONE); 
     } 

的pthread_mutex_lock是必要的或與fgets是線程安全的?我感覺我的代碼有一些問題。

回答

3

你不需要那些。 POSIX保證每個FILE對象都是線程安全的。見http://pubs.opengroup.org/onlinepubs/009695399/functions/flockfile.html

引用(FILE *)對象應表現爲,如果他們 使用flockfile()funlockfile()內部獲得的 這些(FILE *)對象擁有的所有功能。

除非blacklist(ip)是計算密集型,否則鎖定每10個字節實際上會使您的應用程序比完全避免多線程慢得多。

1

C.99不是線程感知的,因此可移植性會要求鎖定到位。然而,C.11使得上的文件操作(C.11 § 7.21.2 ¶ 7)線程安全保證:

每個流具有相關聯的鎖,用於防止數據爭當多個 線程的執行訪問一個流,並且限制由多個線程執行的流操作的交錯 。一次只能有一個線程持有此鎖。該鎖是 可重入:在給定時間,單個線程可能會多次保持該鎖。

在實現方面,如果文件不是很大,你可能會發現它一次性讀取整個文件的性能更高,然後除去線程的輸入。但是,根據我的建議,足夠大的文件將導致序列化I/O成爲瓶頸。此時,我可能會考慮輸入的備選文件表示形式,例如二進制文件格式,並使用異步I/O並且從文件中的多個點並行讀取。