为什么以下函数调用不是线程安全的?

时间:2014-03-28 18:54:41

标签: c multithreading

我使用Sun RPC实现一个简单的伪分布式存储系统。我有三个相同服务器的实例,同一台机器上有一个客户端。

服务器RPC实现如下:

char **
fileread64k_1_svc(char *filename, long offset,  struct svc_req *rqstp)
{

    static char * readResult;
    //chunkName is a function of (fileName, offset)

    FILE *chunkFile = fopen(chunkName, "r");
    readResult = (char *) malloc(sizeof(char) * (CHUNKSIZE + 2));
    fread(readResult, 1, CHUNKSIZE, chunkFile);
    readResult[CHUNKSIZE] = '\0';
    fclose(chunkFile);

    return &readResult;
}

我给我的客户端一个要读取的文件列表,客户端创建3个线程(每个服务器实例一个),线程在其中分配文件,并像这样调用读取RPC:

while all files are not read:
    //pthread_mutex_lock(&lock);
    char **out = fileread64k_1(fileName, offset, servers[id]);
    //char *outData = *out;
    //pthread_mutex_unlock(&lock);

但在我有机会处理它之前,out中的数据被另一个线程替换。如果我启用注释行(互斥锁和outData变量),我会在outData中获取数据,而我似乎可以安全地使用它。

任何人都可以解释为什么会发生这种情况,以及是否有更好的解决方法?

1 个答案:

答案 0 :(得分:2)

因为“readResult”被声明为静态。这意味着该方法的所有调用都在内存中为该变量使用相同的空间,包括不同线程中的并发调用。

如果您不将readResult声明为static,则应该注意这个问题 - 但是在这种情况下,您将无法返回其地址,您应该返回readResult本身的值。

顺便说一下,哪个代码负责free()分配的内存?