【IO】内核提供的原始通信方式(pipe,mkfifo,signal,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:表示之前没有设置定时器

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值