美文网首页
系统编程-------进程编程

系统编程-------进程编程

作者: Hassan_chao | 来源:发表于2017-01-09 08:08 被阅读9次

    多进程编程

    1、进程的创建

    1.1 复制创建新的进程

    fork();

     #include <unistd.h>
     pid_t fork(void);
    

    参数:

    返回值: 成功,子进程的id号,返回给父进程,0返回给子进程;

    ​ 失败,返回-1给父进程,子进程不被创建

    1.2替换创建新的进程

    execl();家族函数

    #include <unistd.h>
    extern char **environ;
    int execl(const char *path, const char *arg, ...);
    int execlp(const char *file, const char *arg, ...);
    int execle(const char *path, const char *arg,..., char * const envp[]);
    

    参数:

    • 第一个参数,指向被执行的文件,
    • 其余的参数以NULL作为结束标志。

    返回值:成功不不返回参数,失败返回-1;

    excev()家族函数

    int execv(const char *path, char *const argv[]);
    int execvp(const char *file, char *const argv[]);
    int execvpe(const char *file, char *const argv[],char *const envp[]);
    

    参数:

    • 第一个参数,指向被执行的文件,
    • 其余的参数以NULL作为结束标志。

    返回值:成功不返回参数,失败返回-1

    2、等待子进程的退出

    wait;

    #include <sys/types.h>
    #include <sys/wait.h>
    pid_t wait(int *status);
    
    

    参数:进程状态

    返回值:成功,返回退出子进程的ID值;失败返回-1;

    waitpid();

    #include <sys/types.h>
    #include <sys/wait.h>
    pid_t waitpid(pid_t pid, int *status, int options);
    

    参数:

    • 处理方式:

      <-1:等待任意子进程,其进程ID为pid绝对值

      -1:等待所有子进程

      0:等待任意组ID等于调用进程

      大于0:等待子进程ID等于pid的值

    • 进程状态

    • 选择值

    返回值:成功返回0;失败返回-1;

    3、进程间信号

    信号处理函数signal

     #include <signal.h>
     typedef void (*sighandler_t)(int);
     sighandler_t signal(int signum, sighandler_t handler);
    

    参数:

    • signum: 指定信号
    • handler:处理函数

    返回值:成功,上一个信号值;失败,返回SIG_ERR

    信号处理函数sigcation

    #include <signal.h>
    int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
    
    struct sigaction {
                   void     (*sa_handler)(int);
                   void     (*sa_sigaction)(int, siginfo_t *, void *);
                   sigset_t   sa_mask;
                   int        sa_flags;
                   void     (*sa_restorer)(void);
               };
    

    参数:

    • signum:指定信号
    • 非空,赋予新的信号
    • 非空,保存以前的信号

    返回值:成功返回0;失败返回-1;

    信号发送函数 kill();

    #include <sys/types.h>
    #include <signal.h>
    int kill(pid_t pid, int sig);
    

    参数:

    • pid = 0;向组内所有进程发送信号
    • pid = -1;向允许发送的所有线程发送,不包含初始进程
    • pid < -1;向组内指定进程(-pid)发送信号

    返回值:成功,返回0;失败,返回-1;

    //信号实例
    #include <stdio.h>
    #include <signal.h>
    
    void sig_handler(int signo);
    
    int main(int argc, char *argv[])
    {
        //typedef void (*sighandler_t)(int);
        //sighandler_t signal(int signum,
        //   sighandler_t handler);
        //signal(2, sig_handler);
        // 为指定信号注册信号处理函数
        signal(SIGINT, sig_handler);
    
        while(1);
    
        return 0;
    }
    
    void sig_handler(int signo)
    {
        printf("hahahaha\n");
    }
    

    进程实例:

    // 练习1:在父进程中为SIGINT信号注册处理函数,然后创建一个子进程,父子进程均进行无限循环,使用Ctrl+c组合键触发SIGINT信号,观察父子进程的执行情况
    // 注意:子进程在创建时会copy当前父进程的信号处理方式
    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    void sig_handler(int signo);
    int main(int argc, char *argv[])
    {
        pid_t pid;
        struct sigaction act;//定义一个act访问sigaction结构体变量
        
        //signal(SIGINT, SIG_IGN);
        //signal(SIGINT, SIG_DFL);
        //signal(SIGINT, sig_handler);
        act.sa_handler = sig_handler;
        //act.sa_handler = SIG_IGN;
        //act.sa_handler = SIG_DFL;
        sigaction(SIGINT, &act, NULL);
        
        pid = fork();
        
        while(1);
    
        return 0;
    }
    
    void sig_handler(int signo)
    {
        switch(signo)
        {
            case SIGINT:
                printf("signal SIGINT catched in process %d\n", getpid());
        }     
    }
    
    // 注意:本例使用信号异步处理僵尸进程
    // 实现原理:当子进程退出时,会向父进程发送SIGCHLD信号,在父进程的SIGCHLD信号处理函数中调用wait函数,防止僵尸进程的产生
    
    // 信号处理函数能够使用其形式参数接收触发该函数的信号值
    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    #include <time.h>
    #include <stdlib.h>
    void sig_handler(int signo);
    
    int main(int argc, char *argv[])
    {
        pid_t pid;
    
        srand(time(NULL));
        
        // sigaction
        signal(SIGCHLD, sig_handler);
    
        while(1)
        {
            pid = fork();
            if(pid == 0)
            {
                printf("child process %d is running...\n",  getpid());
                sleep(rand()%3+1); 
                
                //return 0;
                exit(0); 
            }
            else if(pid > 0)
            {
                sleep(1);
            }
        }
    
        return 0;
    }
    
    // 信号处理函数能够使用其形式参数接收触发该函数的信号值
    void sig_handler(int signo)
    {
        if(signo == SIGCHLD)
        {
            printf("child process %d is exit!!!\n",
                wait(NULL));
        }
    }
    

    相关文章

      网友评论

          本文标题:系统编程-------进程编程

          本文链接:https://www.haomeiwen.com/subject/netcbttx.html