美文网首页
系统编程(2)

系统编程(2)

作者: 酸菜牛肉 | 来源:发表于2017-01-04 20:00 被阅读42次

    进程的创建
    fork(),当返回值为0时,代表为子进程,当返回值为1时,代表为父进程。。用以区分子父进程的作用。。

    • 僵尸进程的产生:
      子进程结束后,父进程还在继续运行但是并未调用wait/waitpid那子进程就会成为僵尸进程即子进程在父进程之前退出
    • 如何防止僵尸进程
      避免僵尸进程主要包含以下几种方法:
      1、父进程使用wait()或者waitpid()之类的函数等待子进程退出
      2、父进程先产生一个子进程,然后子进程再产生一个孙子进程,子进程在孙子进程之前退出。
      3、使用信号函数sigactionSIGCHLD设置wait处理函数。
    • 在父进程中为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;
        
        //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());
        }     
    }
    
    
    • 创建一个子进程,子进程进入一个无限循环,模拟每1秒从数据中心取一个数据并处理的过程,直到子进程收到父进程发送过来的SIGUSR1信号,打印子进程pid,并退出
      父进程:创建子进程之后,循环等待信号的到达,当收到SIGINT(由组合键Ctrl+c模拟)信号之后,向子进程发送一个SIGUSR1信号
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    
    
    pid_t pid;
    
    void parent_process_sig_handler(int signo);
    
    void child_process_sig_handler(int signo);
    
    int main(int argc, char *argv[])
    {    
        signal(SIGINT, parent_process_sig_handler);
        signal(SIGCHLD, parent_process_sig_handler);
    
        if((pid = fork()) == 0)
        {
            signal(SIGINT, SIG_IGN);
            signal(SIGUSR1, child_process_sig_handler);
        
            int client_id = 0;
            
            while(1)
            {    
                client_id = rand()%100+1;
                printf("client %d is in...\n", client_id);
                sleep(1);
                printf("client %d is out...\n", client_id);
            }
        }
        else if(pid > 0)
        {
            while(1);
        }
        else
        {
        }
    
        return 0;
    }
    
    void parent_process_sig_handler(int signo)
    {
        switch(signo)
        {
            case SIGCHLD:
            wait(NULL);   
            break;
            case SIGINT:
            // kill函数向指定进程发送指定信号值
            // 注意,信号发送无法传递数据
            kill(pid, SIGUSR1);
            break;
            default:
            break;
        }
    }
    
    void child_process_sig_handler(int signo)
    {
        if(signo == SIGUSR1)
        {
            printf("child process pid : %d\n", getpid());
            exit(0);
        }
    }
    

    // 实现原理:当子进程退出时,会向父进程发送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));
        }
    }
    
    
    • 创建线程的三个函数
      pthread_create()
      pthread_join()
      pthead_exit()
    
    #include<stdio.h>
    #include<pthread.h>
    
    void *pthread_func(void *arg);
    
    int main(int argc,char *argv[])
    {
        pthread_t pthread_id;
        pthread_create(&pthread_id,NULL,&pthread_func,NULL);
        
        printf("hahahaha__main\n");
        
        pthread_join(&pthread_id,NULL);
        
        
        return 0;
    }
    
    void *pthread_func(void *arg)
    {
        printf("hahaha\n");
        pthread_exit(NULL);
    }
    

    相关文章

      网友评论

          本文标题:系统编程(2)

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