【IO】进程间通信 有关管道,信号函数整理汇总

        本分类用来记录一些函数的知识点,我的目标是看函数,能够知道如何去使用,并且能够想出对应案例的框架结构

目录

1、pipe函数:无名管道的API接口函数

2、mkfifo函数:有名管道的API接口函数

3、signal函数:将信号与信号处理方式连接

4、alarm函数:闹钟函数


1、pipe函数:无名管道的API接口函数

函数原型:

int pipe(int pipefd[2]);

例子:

#include<myhead.h>

int main(int argc, const char *argv[])
{

    //创建用于通信的管道文件,并返回该文件对应的文件描述符
    int pipefd[2] ;
    if(pipe(pipefd)==-1)
    {
        perror("pipe error");
        return -1;
    }


    //创建父子进程
    pid_t pid = fork();
    if(pid < 0)
    {
        perror("fork error");
        return -1;
    }else if(pid  == 0)
    {
        //子进程
        close(pipefd[1]);          //关闭写端
    
        //接受父进程发来的消息
        char rbuf[128] = "";

        while(1)
        {
            bzero(rbuf, sizeof(rbuf));

            //从管道中读取数据
            read(pipefd[0], rbuf, sizeof(rbuf));

            if(strcmp(rbuf, "quit")==0)
            {
                break;
            }

            //输出数据
            printf("收到父进程的来信:%s\n", rbuf);
        }

        //关闭读段
        close(pipefd[0]);


        //退出进程
        exit(EXIT_SUCCESS);
    }

    //父进程
    char sbuf[128] = "";
     //关闭读端
    close(pipefd[0]);
    while(1)
    {        

        usleep(10);
        printf("父进程中输入>>>");
        fgets(sbuf, sizeof(sbuf), stdin);          //从终端获取字符串
        sbuf[strlen(sbuf)-1] = 0;

        //发送给子进程,将数据通过写端写入管道 pipefd[1]
        write(pipefd[1], sbuf, strlen(sbuf));

        //判断终端获取的数据
        if(strcmp(sbuf, "quit") == 0)
        {
            break;
        }

        //关闭写端
        close(pipefd[1]);
    }

    

    //回收子进程资源
    wait(NULL);

    return 0;
}

功能:在通过内核在内存中创建一个无名管道,并通过参数将该管道文件的两个文件描述符返回

参数:接收文件描述符的数组,pipefd[0]表示管道文件的读端,pipefd[1]表示管道的写端

返回值:成功返回0,失败返回-1并置位错误码


2、mkfifo函数:有名管道的API接口函数

函数原型:

int mkfifo(const char *pathname, mode_t mode);

例子:

//create.c
#include<myhead.h>

int main(int argc, const char *argv[])
{
    //创建一个有名管道文件
    if(mkfifo("./linux", 0664)==-1)
    {
        perror("mkfifo error");
        return -1;
    }

    getchar();

    system("rm linux");
    
    return 0;
}
//snd.c
#include<myhead.h>

int main(int argc, const char *argv[])
{
    //以写的形式打开管道文件
    int wfd = open("./linux", O_WRONLY);
    if(wfd == -1)
    {
        perror("open error");
        return -1;
    }
    printf("管道文件已经打开\n");

    //发送数据
    char wbuf[128] = "";
    while(1)
    {
        printf("请输入>>>>");
        fgets(wbuf, sizeof(wbuf), stdin);
        wbuf[strlen(wbuf)-1] = 0;

        //将数据发送给到管道中
        write(wfd, wbuf, strlen(wbuf));

        //判断数据
        if(strcmp(wbuf, "quit") == 0)
        {
            break;
        }
    }

    //关闭文件描述符
    close(wfd);

    
    return 0;
}
//recv.c
#include<myhead.h>

int main(int argc, const char *argv[])
{
    //以读的形式打开文件
    int rfd = open("./linux", O_RDONLY);
    if(rfd == -1)
    {
        perror("open error");
        return -1;
    }
    printf("管道文件读端打开\n");

    //定义接受容器
    char rbuf[128] = "";
    while(1)
    {
        bzero(rbuf, sizeof(rbuf));
        //读取数据
        read(rfd, rbuf, sizeof(rbuf));
        if(strcmp(rbuf, "quit") == 0)
        {
            break;
        }
        printf("收到消息为:%s\n", rbuf);
    }

    //关闭文件描述符
    close(rfd);
    
    return 0;
}

功能:在文件系统中创建一个有名管道,但是并没有打开该文件

返回值:成功返回0,失败返回-1并置位错误码


3、signal函数:将信号与信号处理方式连接

函数原型:

sighandler_t signal(int signum, sighandler_t handler);

例子:

//将2号信号与对应的信号处理函数进行绑定
//尝试忽略2号信号
if(signal(2, SIG_IGN) == SIG_ERR)
{
    perror("signal error");
    return -1;
}

功能:将信号与信号处理函数绑定到一起

参数1:要绑定的信号

参数2:信号处理函数

             SIG_IGN:表示忽略信号

             SIG_DFL:表示默认处理

             填自定义函数的入口地址

返回值:成功返回处理方式的起始地址,失败返回 SIG_ERR


4、alarm函数:闹钟函数

函数原型:

unsigned alarm(unsigned seconds);

例子:

#include<myhead.h>

//定义信号处理函数
void handler(int signo)
{
    if(signo == SIGALRM)
    {
        printf("阎王叫你三更死,怎可留人到五更\n");
        sleep(2);
        exit(EXIT_SUCCESS);
    }
}


/********************主程序******************/
int main(int argc, const char *argv[])
{

    //将SIGALRM信号与信号处理函数绑定
    if(signal(SIGALRM, handler) == SIG_ERR)
    {
        perror("signal error");
        return -1;
    }


    printf("%d\n", alarm(10));          //0

    sleep(5);


    printf("%d\n", alarm(10));          //5


    int count = 0;
    while(1)
    {
        printf("能活一秒是一秒\n");
        sleep(1);
        /*
        count++;
        if(count == 3)
        {
            alarm(0);           //删除定时器
        }
        */
    }

    return 0;
}

功能:给进程设置一个定时器,以秒为单位,当定时器到位后,后向该进程发送一个SIGALRM的信号

返回值:>0:表示返回的上一个定时器剩余的秒数,并且重置上一个定时器

               0:表示之前没有设置定时器

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值