2013-09-05 159 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并且从文件中的多个点并行读取。