星期一, 3月 20, 2006

vfork : uclinux

當初作uclinux時寫的notes(chris和alice也有貢獻)。
最近又要用到,所以copy出來。....


fork和vfork都是產生child process的function call,
fork後好像會先執行child process,再執行parent process。

在uClinux裡,fork不行用,要用vfork,但是vfork和fork不一樣,

vfork的child和parent使用相同的memory space,所以child process不可以直接結束。
要用exit()或是呼叫exec??( )執行其他外部程式來結束自己。

如果不用exit而結束, 會有"Illegal instruction"或是'SIGSEGV"的error message。

另一點
vfork不能像fork一樣,
以下面的fork一個child process作daemon的code來看:
int main(int argc, char *argv[])
{
char c;
int _argc = 0;
char *_argv[3];
pid_t pid;

if ((pid = fork()) < 0) {
fprintf(stderr, "fork failed\n");
exit(1);
} else if (pid != 0) {
exit(0);
}

setsid();
chdir("/");
umask(0);
close(0);
close(1);
close(2);

for (;;) {
sleep(5);
syslog(LOG_INFO, "Still sleeping\n");
}
}
把fork改為vfork後雖然parent有作exit(),但是因為和vfork的parent,child使用相同的
memory space,所以直到child也exit()或exec??()前,parent都無法結束。
所以以vfork來作上面的例子:
int execed = 0;

int main(int argc, char *argv[])
{
char c;
int _argc = 0;
char *_argv[3];
pid_t pid;

while ((c=getopt(argc, argv, "D")) > 0) {
switch(c) {
case 'D':
execed = 1;
break;
default:
fprintf(stderr, "You probably don't want to pass "
"options to this\n");
exit(1);
}
}

if (!execed) {
if ((pid = vfork()) < 0) {
fprintf(stderr, "vfork failed\n");
exit(1);
} else if (pid != 0) {
exit(0);
}

_argv[_argc++] = argv[0];
_argv[_argc++] = "-D";
_argv[_argc++] = NULL;
execv(_argv[0], _argv);
/* Not reached */
fprintf(stderr, "Couldn't exec\n");
_exit(1);
} else {
setsid();
chdir("/");
umask(0);
close(0);
close(1);
close(2);
}

for (;;) {
sleep(5);
syslog(LOG_INFO, "Still sleeping\n");
}
}
Link: http://www.ucdot.org/article.pl?sid=03/12/12/0317219&mode=thread

還有vfork是child先執行,結束後才將控制權交給parent,和fork不一樣。
所以vfork還是無法做到讓兩個process同時動作:
main()
{
int status;
if (vfork()==0) {
printf("child go\n");
sleep(10);
printf("child up\n");
exit(0);
}else{
printf("parent go\n");
wait(&staus);
printf("parent end\n");
}
}
上面的程式如果是用linux的fork,會在child sleep時,將控制權交給parent。
 child go
parent go
child up
parent end
但是用vfork的話,在child執行exit()之前,parent都不會拿到控制權,所以

child go
child up
parent go
parent end
.

沒有留言:

網誌存檔