Unix/Linux编程实践教程 笔记8 进程和程序:编写命令解释器sh

ps -a
-a选项列出所有进程,包括在其他终端由其他用户运行的程序,但是带选项-a的输出并不包括shell。
ps -l

administrator@ubuntu:~$ ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 R  1000  7600  6949  1  80   0 -  1585 -      pts/0    00:00:00 bash
0 R  1000  7617  7600  0  80   0 -   628 -      pts/0    00:00:00 ps

名为S的一列表示各个进程的状态,S列的值为R说明ps对应的进程正在进行。其他进程S列值都是S,说明他们都处于睡眠状态。每个进程都属于相应的由UID列指明的用户ID。每个进程都有一个进程ID,同时也有一个父进程ID。
PRI:进程的优先级
NI:niceness级别
SZ:所占内存的大小
WCHAN: 显示进程睡眠的原因。read_c do_sel代表内核的地址

#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
int main()
{
    char *arglist[3];
    arglist[0]="ls";
    arglist[1]="-l";
    arglist[2]=0;
    printf("***About to exec ls -l\n");
    execvp("ls",arglist);
    printf("have done\n");
    return 0;
}

administrator@ubuntu:~/test$ ./exec1
***About to exec ls -l
总用量 36
-rwxr-xr-x 1 administrator administrator 9083 2009-05-26 15:22 exec1
-rw-r--r-- 1 administrator administrator  237 2009-05-26 15:22 exec1.c
-rw-r--r-- 1 administrator administrator  992 2009-05-26 15:21 exec1.o
-rwxr-xr-x 1 administrator administrator 9118 2009-05-18 14:08 execlp
-rw-r--r-- 1 administrator administrator  251 2009-05-18 14:08 execlp.c

execvp有两个参数:要运行的程序名和那个程序的命令行参数数组。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXARGS 20
#define ARGLEN 100
int main()
{
    char *arglist[MAXARGS+1];
    int numargs;
    char argbuf[ARGLEN];
    char *makestring();
    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;
}


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;
}


一个进程以三种方式(成功,失败或死亡)之一结束。
1 一个进程可能顺利完成它的任务
2 进程可能失败exit(非0值)
3 进程被一个信号杀死,信号可能来自键盘、间隔计时器、内核或者其他进程

wait()返回结束的子进程的PID给父进程,父进程如何知道子进程是以何种方式退出的呢?
答 案在传给wait的参数之中,父进程调用wait时传一个整形变量地址给函数,如果子进程调用exit退出,那么内核就把exit的返回值存放在这个整数 变量中;如果进程是被杀死的,那么内核将信号序号存放在这个变量中。这个整数由3部分组成--8个bit是记录退出值,7个bit是记录信号序列,另一个 bit用来指明发生错误并产生内核映像(core dump)

你可能感兴趣的:(linux)