1

如果它们被列入黑名单(使用多线程),我想检查 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 是线程安全的?我觉得我的代码有一些问题。

4

2 回答 2

4

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

引用 ( ) 对象的所有函数的FILE *行为应如同它们使用flockfile()funlockfile()在内部获得这些 ( FILE *) 对象的所有权一样。

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

于 2013-09-05T18:07:28.357 回答
1

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

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

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

于 2013-09-05T17:51:39.333 回答