在多线程程序中访问文件指针时出错

时间:2012-06-29 17:26:10

标签: c file-io parallel-processing cilk

我想问的是一些大代码的一部分,但我会尽量缩短它。我将首先从我的代码中解释相关的代码片段然后再解释我得到的错误。

来自主要功能内的main.c

cilk_for ( line_count = 0; line_count != no_of_lines ; ++line_count )
{
     //some stuff here
     for ( j=line_count+1; j<no_of_lines; ++j )
     {
         //some stuff here
         final_result[line_count][j] = bf_dup_eleminate ( table_bloom[line_count], file_names[j], j );
         //some stuff here
     }
     //some stuff here
}
来自bf_dup_eleminate文件的

bloom-filter.c函数:

int bf_dup_eleminate ( const bloom_filter *bf, const char *file_name, int j )
{
    int count=-1;
    FILE *fp = fopen (file_name, "rb" );
    if (fp)
    {
        count = bf_dup_eleminate_read ( bf, fp, j);
        fclose ( fp );
    }
    else
    {
        printf ( "Could not open file\n" );
    }
    return count;
}
来自bf_dup_eleminate_read档案的

bloom-filter.c

int bf_dup_eleminate_read ( const bloom_filter *bf, FILE *fp, int j )
{
    //some stuff here
    printf ( "before while loop. j is %d ** workder id: **********%d***********\n", j, __cilkrts_get_worker_number());
    while (/*somecondition*/)
    {/*some stuff*/}
    //some stuff
}

这是一个多线程应用程序(我通过强制它使用两个线程来运行它)我可以确定第一个线程到达printf语句(因为它是用线程信息输出的)。现在gdb告诉我你有以下错误

0x0000000000406fc4 in bf_dup_eleminate_read (bf=<error reading variable: Cannot access memory at address 0x7ffff7edba58>, fp=<error reading variable: Cannot access memory at address 0x7ffff7edba50>, j=<error reading variable: Cannot access memory at address 0x7ffff7edba4c>) at bloom-filter.c:536

Line 536int bf_dup_eleminate_read ( const bloom_filter *bf, FILE *fp, int j )

错误信息非常清楚,但我不知道为什么会发生这种情况。我想不出为什么会这样。确保打开文件(因为函数bf_dup_eleminate中的错误消息未打印)。另外我相信如果两个线程正在执行相同的代码行,那么它们将为所有局部变量分别进行实例化。鉴于可能是什么问题。

任何帮助表示赞赏!!

P.S。:cilk_for关键字只是一个在运行时产生线程的构造。

当使用的线程数为1时,程序运行。

1 个答案:

答案 0 :(得分:0)

似乎当你通过引用传递变量时,我的意思是table_bloom [line_count],它将指针传递给所有线程。所以所有线程都试图同时访问指针值。您可以尝试制作每个参数的副本,然后将其传递给bf_dup_eleminate_read。 未经测试的代码:

int bf_dup_eleminate ( const bloom_filter *bf, const char *file_name, int j )
{
    bloom_filter *t_bf = bf;

    int count=-1;
    FILE *fp = fopen (file_name, "rb" );
    if (fp)
    {
        count = bf_dup_eleminate_read (t_bf, fp, j);
        fclose ( fp );
    }
    else
    {
        printf ( "Could not open file\n" );
    }
    return count;
}

或者这不起作用,尝试制作每个参数的硬拷贝:

    bloom_filter t_bf = *bf; //forgot how struct copying is done
    char *t_filename = strdup(filename);
    int t_j = j; //not required

如果你不能复制,那么可以使用互斥锁。见link