疯狂的兔子li
境由心生

今晚开始不断电。

最近小组纳新生源质量又不高,虽然最近各种忙,很疲惫,但还是想朝着目标更进一步,所以就想今晚想看看渗透方面的知识,看着看着看到了代码,就想到了昨天请教韬哥的这题,所以现在赶紧写下来。

原题是这样:

给 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");
}

父进程结束,程序结束。 

posted on 2013-05-14 02:15  疯狂的兔子li  阅读(113)  评论(0编辑  收藏  举报