使用多线程读取文件

时间:2013-09-05 17:44:43

标签: c multithreading pthreads mutex fgets

我想检查一下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是线程安全的?我觉得我的代码存在一些问题。

2 个答案:

答案 0 :(得分:4)

你不需要那些。 POSIX保证每个FILE对象都是线程安全的。见http://pubs.opengroup.org/onlinepubs/009695399/functions/flockfile.html

  

引用(FILE *)对象的所有函数都应该像它们一样   在内部使用flockfile()funlockfile()获取所有权   这些(FILE *)个对象。

除非blacklist(ip)是计算密集型的,否则锁定每10个字节实际上会使您的应用程序比完全避免多线程更慢。

答案 1 :(得分:1)

C.99不是线程感知的,因此可移植性要求锁定到位。但是,C.11对文件操作提出了线程安全保证(C.11§7.21.2¶7):

  

每个流都有一个关联的锁,用于防止多个数据争用   执行线程访问流,并限制流操作的交错   由多个线程执行。一次只有一个线程可以保持此锁定。锁是   可重入:单个线程可以在给定时间多次保持锁定。

在实现方面,如果文件不是很大,您可能会发现一次性读取整个文件的性能更高,然后为线程划分输入。但是,根据我的提议,足够大的文件会导致序列化I / O成为瓶颈。此时,我可能会考虑输入的替代文件表示,例如二进制文件格式,并使用异步I / O并并行读取文件中的多个点。