linux之eventfd()

参考:https://www.man7.org/linux/man-pages/man2/eventfd.2.html

一、简介

简单来说,这个函数就是创建一个用于事件通知的文件描述符。它类似于pipe,但是不像pipe一样需要两个描述符,它只需要一个描述就可以实现进程间通信了

二、使用

实例

#include <sys/eventfd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h> /* Definition of uint64_t */

#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char **argv)
{
    int efd, j;
    uint64_t u;
    ssize_t s;

    if (argc < 2)
    {
        fprintf(stderr, "Usage: %s <num>...\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    efd = eventfd(0, 0);
    if (efd == -1)
    {
        handle_error("eventfd");
    }

    switch (fork()) 
    {
        case 0: //子进程
            for (j = 1; j < argc; j++)
            {
                printf("Child writing %s to efd\n", argv[j]);
                u = strtoull(argv[j], NULL, 0);
                s = write(efd, &u, sizeof(uint64_t));
                if (s != sizeof(uint64_t))
                {
                    handle_error("write");
                }
            }
            printf("Child completed write loop\n");
            exit(EXIT_SUCCESS);
        case -1:  创建进程失败
            handle_error("fork");

        default: //父进程,父进程中子进程pid与子进程中pid不同
            sleep(2);

            printf("Parent about to read\n");
            s = read(efd, &u, sizeof(uint64_t));
            if (s != sizeof(uint64_t))
            {
                handle_error("read");
            }
            printf("Parent read %llu (0x%llx) from efd\n", (unsigned long long)u, (unsigned long long)u);
            exit(EXIT_SUCCESS);
    }
}

执行结果:

三、扩展

fork()函数

函数原型

#include <unistd>
pid_t fork(void);

 一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    int flag = 0;
    pid_t pid = fork();
    if(pid == -1) //失败
    {   
        perror("fork error"); 
        exit(EXIT_FAILURE);  
    }
    else if(pid == 0)//子进程
    {
        int childpid = getpid();
        int parentpid = getppid();
        int count = 0;
        printf("子进程输出:父进程pid为:%d。子进程pid为%d\n",parentpid,childpid);
        flag = 123;
        printf("子进程输出:输出子类flag:%d。该地址为:%p\n",flag,&flag);
        while(1)
        {
            count ++;
            sleep(1);
            printf("子进程计数开始:%d\n",count);
            if(count >=  5)
                break;
        }
    }
    else//父进程,父进程中子进程pid与子进程中pid不同
    {
        flag = 456;
        int mypid = getpid();
        int count = 0;
        printf("父进程输出:父进程pid为:%d。子进程pid为%d\n",mypid,pid);
        printf("父进程输出:输出子类flag:%d。该地址为:%p\n",flag,&flag);
        while(1)
        {
            count ++;
            sleep(1);
            printf("父进程计数开始:%d\n",count);
            if(count >=  2)
                break;
        }
    }
    printf("最后的flag为:%d\n",flag);
    return EXIT_SUCCESS;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值