wait函数

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阅读笔记系列,后续会讲到系统调用机制的!

你可能感兴趣的:(编程)