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

2017-01-09  本文已影响9人  Hassan_chao

多进程编程

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[]);

参数:

返回值:成功不不返回参数,失败返回-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[]);

参数:

返回值:成功不返回参数,失败返回-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);

参数:

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

3、进程间信号

信号处理函数signal

 #include <signal.h>
 typedef void (*sighandler_t)(int);
 sighandler_t signal(int signum, sighandler_t 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);
           };

参数:

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

信号发送函数 kill();

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

参数:

返回值:成功,返回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));
    }
}
上一篇下一篇

猜你喜欢

热点阅读