你脑海中的问题答案:是的,这是为学校而做的。不,我不能使用线程来解决这个问题。是的,我寻找了答案,有些人说“是”,有些人说“不是”。我还在核实我的教授,因为我不希望因为别人要求这个问题“修复”而不公平地失去分数。
说了这么多,考虑一下Linux系统上的C语言简单程序。我申请了一些内存,然后进行了fork操作。我将我的项目简化到了一个确切的问题:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main( void )
{
char * args [] = { "someinvalidcommand", NULL };
// malloc before the fork (happens in parent process)
char * something = (char *)malloc(sizeof(char));
pid_t child_pid = fork();
// are there now two things that need to be freed:
// one for each process?
if(child_pid == 0) // child process
{
//free(something); // is this needed?
// execvp (it won't return if succeeded)
if(execvp(args[0], args) < 0)
{
// or do I only need to free it here?
printf("%s: No such file or directory\n", args[0]);
/*
* EDIT: Calling it here seems to fix the issue. It turns out
* that the system calls were the ones with the "still reachable"
* errors, so I guess it's not all that important that the
* memory be freed.
*
* free(something)
*/
_exit(1);
}
}
else // parent process
{
int status;
while(wait(&status) != child_pid);
if(status != 0)
{
printf("command status: %i\n", WEXITSTATUS(status));
}
}
free(something);
return 0;
}
现在问题有点混乱。据我所知,fork会在特定状态下创建父进程的完全副本(包括文本、数据等)。我在某个地方读到过这包括任何malloc'd内容(即堆)。然而,我在别的地方读到它不包括堆,因为有一个叫做“写时复制”的东西,但是我在别的地方又读到,“写时复制”只是一种透明且无关紧要的优化。但是最有道理的是,既然它是一个COPY,那么它有自己的一切。
但是我记得当使用fork()时,任何被malloc的内容将包含相同的内存地址,所以父进程和子进程指向同一物体吗?我需要在子进程中释放资源吗?只有指针被复制了,还是指针指向的数据也被复制了?
我使用了valgrind,当子进程退出时,它只是抱怨所有的内存仍然可以访问。它“仍然可以访问”是什么意思?事实上,它“仍然可以访问”回答了我的问题,并表示父进程是唯一负责释放内存的。