美文网首页
系统编程(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);
}

相关文章

  • Linux/UNIX系统编程手册-基本概念

    Linux/UNIX系统编程手册 [德] Michael Kerrisk 第2章 基本概念第3章 系统编程概念 基...

  • 系统编程(2)

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

  • 人月神话

    1.程序,编程产品,编程系统,编程系统产品 2.创造性活动:构思,实现,交流 3.团队建立 4.概念的一致性 5....

  • 2017年10月24日

    大数据系统基础 4.7-4.14《Hive编程指南》第1章《Hive编程指南》第2章《Hive编程指南》第3章

  • 嵌入式LINUX开发三步走

    第一学习阶段,主要打好基础,学好C编程,Linux系统编程。 1、C语言编程基础 2、嵌入式开发基础:Linux概...

  • python系统编程2

    线程 1.1.1 多线程——threading python的thread模块是比较底层的模块,python的th...

  • Linux系统编程2

    一、task_struct结构体 FD表中的FD指针会指向一个file结构体,这个【file结构体】是处于内核空间...

  • 20180915短期方向明确

    1.C++ 实践方向 2.网络编程 3.多线程编程 4.操作系统 5.分布式系统(知乎上面MIT的课程) stri...

  • SpringBoot AOP的使用

    Spring框架核心之一,面向切面编程。 1、使用场景 系统日志处理 系统事务处理 系统安全验证 系统数据缓存 2...

  • 进程线程-导读

    一:引出 进程线程与文件IO一起,一般也叫做系统编程,系统编程,顾名思义,就是与操作系统有关系的编程,那么系统编程...

网友评论

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

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