我使用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
中获取数据,而我似乎可以安全地使用它。
任何人都可以解释为什么会发生这种情况,以及是否有更好的解决方法?
答案 0 :(得分:2)
因为“readResult”被声明为静态。这意味着该方法的所有调用都在内存中为该变量使用相同的空间,包括不同线程中的并发调用。
如果您不将readResult声明为static,则应该注意这个问题 - 但是在这种情况下,您将无法返回其地址,您应该返回readResult本身的值。
顺便说一下,哪个代码负责free()分配的内存?