linux进程编程

    技术2022-05-20  36

     

    创建一个新进程    1.可以使用system函数在程序里创建一个新的进程,函数定义如下:          int system (const char *string);        string代表运行的命令。   2.可以使用以exec开头的一系列函数来开始一个新进程,这些函数有:       int execl(const char *path, const char *arg0, ..., (char *)0);        int execlp(const char *file, const char *arg0, ..., (char *)0);        int execle(const char *path, const char *arg0, ..., (char *)0, char *constenvp[]);        int execv(const char *path, char *const argv[]);        int execvp(const char *file, char *const argv[]);        int execve(const char *path, char *const argv[], char *const envp[]);      这些函数分为两类。execl,execlp和execle使用可变数目的参数,最末尾的参数则是一个空指针。execv和execvp的第二个参数是一个字符串数组。两种情况下,参数的值都是传到新建的进程的main函数的argv参数里。但最通常使用的是execve函数。        #include <unistd.h> /* Example of an argument list */ /* Note that we need a program name for argv[0] */ char *const ps_argv[] = {"ps", "ax", 0}; /* Example environment, not terribly useful */ char *const ps_envp[] = {"PATH=/bin:/usr/bin", "TERM=console", 0}; /* Possible calls to exec functions */ execl("/bin/ps", "ps", "ax", 0); /* assumes ps is in /bin */ execlp("ps", "ps", "ax", 0); /* assumes /bin is in PATH */ execle("/bin/ps", "ps", "ax", 0, ps_envp);/* passes own environment */ execv("/bin/ps", ps_argv); execvp("ps", ps_argv); execve("/bin/ps", ps_argv, ps_envp); 复制一个进程       也是创建一个新进程,但是新的进程先复制当前的进程,在进程表里获得一个新的ID,新的进程与原有进程使用相同的代码但有自己独立的数据空间和文件描述符,函数定义如下:       pid_t fork(void);       父进程里调用的fork函数返回的是子进程的PID,新的子进程按照父进程的代码继续往下执行,但在子进程里fork函数的返回值是0。这样子进程和父进程就得以区分。下面的例子演示了如何使用fork函数复制一个新进程: #include<sys/types.h> #include<unistd.h> #include<stdio.h> #include<stdlib.h> int main() { pid_t pid; char *message; int n; 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; break; default: message = "This is the parent"; n = 3; break; } for(; n > 0; n--) { puts(message); sleep(1); } exit(0); } 运行结果可能如下: $ ./fork1 fork program starting This is the child This is the parent This is the parent This is the child This is the parent This is the child $ This is the child This is the child 等待一个进程 有时候希望父进程与子进程的运行能够同步,当父进程比子进程运行快时,父进程可以调用wait函数使该进程暂停直到子进程结束。该函数的定义如下:

           pid_t wait(int *stat_loc);

    下面是该函数的使用示例,将以下代码插入上面的程序。

    首先添加一个变量定义:

    int exit_code;  

    在case 0里添加代码:

    exit_code = 37;  

    在case 1里添加代码:

    exit_code = 0;  

    在最后的exit前添加以下代码:

    if (pid != 0) { int stat_val; pid_t child_pid; child_pid = wait(&stat_val); printf("Child has finished: PID = %d/n", child_pid); if(WIFEXITED(stat_val)) printf("Child exited with code %d/n", WEXITSTATUS(stat_val)); else printf("Child terminated abnormally/n"); }

    运行结果可能如下:

    $ ./wait

    fork program starting

    This is the child

    This is the parent

    This is the parent

    This is the child

    This is the parent

    This is the child

    This is the child

    This is the child

    Child has finished: PID = 1582

    Child exited with code 37

     

     

    僵尸进程

         当子进程先结束,而父进程还在运行时,子进程在进程表里依然保存一个入口,但子进程本身已经不是活动的了,这种情况称为僵尸进程。

     

    信号

         信号是linux系统里对某些情况(如:产生错误)产生的事件,这样的事件产生后可能引起某个进程的某个动作,信号能够被发送,捕捉,响应以及忽略。在signal.h包含了关于信号的函数和数据定义。如函数signal,定义如下:

     

    void (*signal(int sig, void (*func)(int)))(int);

         参数sig表示发送的信号的类型,后面的函数指针表示进程接收到信号后将要执行的动作。关于signal的具体使用以及一些其它signal函数请参阅《Begining Linux Programming 4th edition》。

     

     


    最新回复(0)