今晚开始不断电。
最近小组纳新生源质量又不高,虽然最近各种忙,很疲惫,但还是想朝着目标更进一步,所以就想今晚想看看渗透方面的知识,看着看着看到了代码,就想到了昨天请教韬哥的这题,所以现在赶紧写下来。
原题是这样:
给 if 一个任意条件,使打印 Welcome to Xiyou linux!
int main( void )
{
if(____)
{
printf("Welcome to");
}
else
{
printf("Xiyou linux!\n");
}
return 0;
}
答案有各种各样的,在此说两种较巧妙的。
1) !fork || ! wait()
2) !printf( "Welcome to" );
第二种解法就不说了,关键是第一种解法,太巧秒了。
①首先利用 fork 出一个进程,来拷贝下面的代码段。这样在父进程和子进程之中有了两份输出语句了。现在就考虑如何让各自输出不同的一段。
②我们知道,fork 在父进程中的返回值是子进程的pid,在子进程中的返回值是0。这样,在 if 语句中执行 fork 的时候,紧接着就利用 fork 的返回值进行了判断。利用这个返回值,我们进行逻辑非运算。这样下来,子进程则执行 if 后面的语句,而父进程则执行 else语句。这样,正好解决了①中的问题。
③输出了不同的一段,现在又有个问题--进程同步问题。如何保证谁先输出,后输出呢?没搞好输出是:
Xiyou linux!
Welcome to
④利用wait,来实行进程同步。这样来保证输出的顺序。
⑤这里又巧妙的引入了一个逻辑或运算。
在父进程中,由于前面的 !fork 的值为0,则执行后面语句。这时候,再执行wait,来保证让子进程先执行。
⑥这时候,问题又出现了,wait函数父进程的返回值是子进程的状态码。由于子进程成功执行,则状态码为子进程的pid,这样在 if 判断的时候,则执行了 if 中
{
printf("Welcome to");
}
而不是 else中
{
printf("Xiyou linux!\n");
}
所以,这时候,我们再对 wait 的返回值进行逻辑非运算,来保证父进程执行 else语句。
⑦最终,完美的实现了这一过程:
父进程fork出子进程---->父进程判断出 !fork() 值为0,执行或运算后面语句---->执行wait函数,等待子进程结束。这时候,子进程已经fork成功---->由于子进程返回值为0,进行逻辑非后,为1---->则不执行wait函数,直接执行
{
printf("Welcome to");
}
---->不执行else语句---->子进程结束---->wait函数得到子进程pid---->逻辑非运算后,if 判断条件值还是为0---->执行
{
printf("Xiyou linux!\n");
}
父进程结束,程序结束。