void main()
{
pid_t pid;
char message;
int n;
int exit_code;
printf(“fork program starting\n”);
pid=fork();
switch(pid)
{
case -1:
perror(“fork failed”);
exit(1);
case 0:
message=“this is the child”;
n=5;
exit_code=37;
break;
default:
message=“this is the parent”;
n=3;
exit_code=0;
break;
}
for(;n>0;n–)
{
puts(message);
sleep(1);
}
if(pid!=0)
{
int stat_val;
pid_t child_pid;
child_pid=wait(&stat_val);
printf(“child has finished:pid=%d\n”,child_pid);
printf("%d\n",stat_val);
/
if(WIFEXITED(stat_val))
printf(“child exited with code %d\n”,WEXITSTATUS(stat_val));
else
printf(“child terminated\n”);
*/
}
exit(exit_code);
}
这也是引自那个linux c程序设计之类的书里面的代码
再给你们来点内核部分的代码
void Init()
{
int fd_stdin = open("/dev_tty0", O_RDWR);
assert(fd_stdin == 0);
int fd_stdout = open("/dev_tty0", O_RDWR);
assert(fd_stdout == 1);
printf("Init() is running ...\n");
int pid = fork();
if (pid != 0) { /* parent process */
printf("parent is running, child pid:%d\n", pid);
int s;
int child = wait(&s);
printf("child (%d) exited with status: %d.\n", child, s);
}
else { /* child process */
printf("child is running, pid:%d\n", getpid());
exit(123);
}
while (1) {
int s;
int child = wait(&s);
printf("child (%d) exited with status: %d.\n", child, s);
}
}
这个代码引自orange’s一个操作系统的书,后续的代码也是来自于此,看到了wait(s)了吗?那么s到底返回什么东西呢?让我们继续看代码
PUBLIC int wait(int * status)
{
MESSAGE msg;
msg.type = WAIT;
send_recv(BOTH, TASK_MM, &msg);
*status = msg.STATUS;
return (msg.PID == NO_TASK ? -1 : msg.PID);
}
原来是返回-1或者pid来的啊,主意这里采用的是消息队列的方式来做系统调用。我们继续看代码。
PUBLIC void do_wait()
{
int pid = mm_msg.source;
int i;
int children = 0;
struct proc* p_proc = proc_table;
for (i = 0; i < NR_TASKS + NR_PROCS; i++,p_proc++) {
if (p_proc->p_parent == pid) {
children++;
if (p_proc->p_flags & HANGING) {
cleanup(p_proc);
return;
}
}
}
if (children) {
/* has children, but no child is HANGING */
proc_table[pid].p_flags |= WAITING;
}
else {
/* no child at all */
MESSAGE msg;
msg.type = SYSCALL_RET;
msg.PID = NO_TASK;
send_recv(SEND, pid, &msg);
}
}
继续来段代码
PUBLIC int send_recv(int function, int src_dest, MESSAGE* msg)
{
int ret = 0;
if (function == RECEIVE)
memset(msg, 0, sizeof(MESSAGE));
switch (function) {
case BOTH:
ret = sendrec(SEND, src_dest, msg);
if (ret == 0)
ret = sendrec(RECEIVE, src_dest, msg);
break;
case SEND:
case RECEIVE:
ret = sendrec(function, src_dest, msg);
break;
default:
assert((function == BOTH) ||
(function == SEND) || (function == RECEIVE));
break;
}
return ret;
}
继续
PUBLIC void task_mm()
{
init_mm();
while (1) {
send_recv(RECEIVE, ANY, &mm_msg);
int src = mm_msg.source;
int reply = 1;
int msgtype = mm_msg.type;
switch (msgtype) {
case FORK:
mm_msg.RETVAL = do_fork();
break;
case EXIT:
do_exit(mm_msg.STATUS);
reply = 0;
break;
/* case EXEC: */
/* mm_msg.RETVAL = do_exec(); */
/* break; */
case WAIT:
do_wait();
reply = 0;
break;
default:
dump_msg("MM::unknown msg", &mm_msg);
assert(0);
break;
}
if (reply) {
mm_msg.type = SYSCALL_RET;
send_recv(SEND, src, &mm_msg);
}
}
}
其实答案我们早就得到了!这就是wait,还有一些代码没有复制粘贴出来,系统调用的机制实在不是一两篇博客就能讲明白的,有兴趣的可以看我的系列教程,orange阅读笔记系列,后续会讲到系统调用机制的!