20135201李辰希第十二周实践代码

学习计时:共xxx小时

读书:

代码:

作业:

博客:

一、学习目标


掌握进程控制
掌握信号处理的方法
掌握管道和fifo进行进程间通信的方法

二、学习资源

 

 编译、运行、阅读、理解process.tar.gz压缩包中的代码

三、学习方法

1.  进度很重要:必须跟上每周的进度,阅读,练习,问答,项目。我会认真对待每一位同学,请你不要因为困难半途而废。

2. 问答很重要:遇到知识难点请多多提问,这是你的权利更是您对自己负责的义务。问答到博客园讨论小组:http://group.cnblogs.com/103791/
3. 实践很重要:解决书中习题,实践书中实例,完成每周项目,才算真的消化了这本好书。通过实验楼环境或自己安装的虚拟机在实践中进行学习
4. 实验报告很重要:详细记录你完成项目任务的思路,获得老师点评和帮助自己复习。学习完成后在博客园中(http://www.cnblogs.com/)把学习过程通过博客发表,博客标题“信息安全系统设计基础第三周学习总结”

 

四、学习任务

(提示:请将要求学生完成的任务、测验或思考题列在此处)


 编译、运行、阅读、理解process.tar.gz压缩包中的代码

 

、后续学习预告(可选):

第十二章《并发编程》

、学习过程

一. execvp()函数:execvp()会从PATH 环境变量所指的目录中查找符合参数file 的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件。 

 exec1.c

 

#include <stdio.h>

#include <unistd.h>

int main()

{

    char    *arglist[3];

    arglist[0] = "ls";

    arglist[1] = "-l";

    arglist[2] = 0 ;//NULL

    printf("* * * About to exec ls -l\n");

    execvp( "ls" , arglist );

    printf("* * * ls is done. bye");

    return 0;

}

exec1.c、exec2.c、exec3.c运行结果一样。

 

二. fork()函数:在Unix/Linux中用fork函数创建一个新的进程。进程是由当前已有进程调用fork函数创建,分叉的进程叫子进程,创建者叫父进程。该函数的特点是调用一次,返回两次,一次是在父进程,一次是在子进程。两次返回的区别是子进程的返回值为0,父进程的返回值是新子进程的ID。子进程与父进程继续并发运行。如果父进程继续创建更多的子进程,子进程之间是兄弟关系,同样子进程也可以创建自己的子进程,这样可以建立起定义关系的进程之间的一种层次关系。

 

调用fork函数之后内核的工作过程

1.分配新的内存块和内核数据结构

2.复制原来的进程到新的进程

3.向运行进程集添加新的进程

4.将控制返回给两个进程

 

forkdemo.c

#include    <stdio.h>

#include<stdlib.h>

#include<unistd.h>

 

int main()

{

    int fork_rv;

 

    printf("Before: my pid is %d\n", getpid());

 

    fork_rv = fork();       /* create new process   */

 

    if ( fork_rv == -1 )        /* check for error  */

        perror("fork");

 

    else if ( fork_rv == 0 ){

        printf("I am the child.  my pid=%d\n", getpid());

        printf("parent pid= %d, my pid=%d\n", getppid(), getpid());

        exit(0);

    }

 

    else{

        printf("I am the parent. my child is %d\n", fork_rv);

        sleep(10);

        exit(0);

    }

 

    return 0;

}

fork有五个程序,其中forkdemo2.c的子进程不是从main函数开始,而是从fork返回的地方开始被创建。

 

三.psh1.c:psh1.c是Unix shell的第一个方案,要求每个字符串单独输入,第一个是程序名,然后依次是程序参数。

 

代码中

1.一个字符串,一个字符串构造参数列表argist,最后在数组末尾加上NULL;

2.将arglist[0]和arglist数组传给execvp。

3.程序正常运行,execvp命令指定的程序代码覆盖了shell程序代码,并在命令结束之后退出,shell就不能再接受新的命令。

 

#include    <stdio.h>

#include    <stdlib.h>

#include    <string.h>

#include<unistd.h>

 

#define MAXARGS     20             

#define ARGLEN      100            

 

int execute( char *arglist[] )

{

    execvp(arglist[0], arglist);       

    perror("execvp failed");

    exit(1);

}

 

char * makestring( char *buf )

{

    char    *cp;

 

    buf[strlen(buf)-1] = '\0';     

    cp = malloc( strlen(buf)+1 );      

    if ( cp == NULL ){         

        fprintf(stderr,"no memory\n");

        exit(1);

    }

    strcpy(cp, buf);       

    return cp;         

}

 

int main()

{

    char    *arglist[MAXARGS+1];       

    int     numargs;           

    char    argbuf[ARGLEN];        

 

    numargs = 0;

    while ( numargs < MAXARGS )

    {                  

        printf("Arg[%d]? ", numargs);

        if ( fgets(argbuf, ARGLEN, stdin) && *argbuf != '\n' )

            arglist[numargs++] = makestring(argbuf);

        else

        {

            if ( numargs 0 ){      

                arglist[numargs]=NULL; 

                execute( arglist );

                numargs = 0;       

            }

        }

    }

    return 0;

}

 

四.wait

 

1.waitdemo1.c:进程通过调用wait函数等待子进程的退出。wait首先暂停调用它的进程直到子进程结束,然后wait取得子进程结束时传给exit的值。显示了子进程调用exit触发wait返回父进程的过程。

 

2.waitdemo2.c:显示了wait函数告诉父进程子进程是如何结束的,通过传递给wait的参数。父进程调用wait时传一个整型变量地址给函数,内核将子进程的退出状态保存在这个变量之中。

wait的两个重要特征:

1.wait阻塞调用它的程序直到子进程结束

2.wait返回结束进程的PID

 

#include    <stdio.h>

#include<stdlib.h>

#include<sys/types.h>

#include<sys/wait.h>

#include<unistd.h>

 

#define DELAY   10

 

void child_code(int delay)

{

    printf("child %d here. will sleep for %d seconds\n", getpid(), delay);

    sleep(delay);

    printf("child done. about to exit\n");

    exit(27);

}

 

void parent_code(int childpid)

{

    int wait_rv;   

    int child_status;

    int high_8, low_7, bit_7;

 

    wait_rv = wait(&child_status);

    printf("done waiting for %d. Wait returned: %d\n", childpid, wait_rv);

 

    high_8 = child_status >> 8; /* 1111 1111 0000 0000 */

    low_7  = child_status & 0x7F;   /* 0000 0000 0111 1111 */

    bit_7  = child_status & 0x80;   /* 0000 0000 1000 0000 */

    printf("status: exit=%d, sig=%d, core=%d\n", high_8, low_7, bit_7);

}

 

int main()

{

    int  newpid;

 

    printf("before: mypid is %d\n", getpid());

 

    if ( (newpid = fork()) == -1 )

        perror("fork");

    else if ( newpid == 0 )

        child_code(DELAY);

    else

        parent_code(newpid);

}

 

五.视频总结:

视频中主要讲了管道。

1. Linux下的各种进程间通信方式包括:管道、命名管道、消息队列、共享内存、信号量。

20135201李辰希第十二周实践代码_第1张图片

20135201李辰希第十二周实践代码_第2张图片

 

20135201李辰希第十二周实践代码_第3张图片

 

 

 

 

 

七、遇到的问题及解决

(提示:此处由学生填写,是重要的得分点,要写出遇到的问题和解决方案以及对出现问题的思考)

 

 

 

八、其他

linux好难啊!!!!

==========================================================
 

你可能感兴趣的:(20135201李辰希第十二周实践代码)