参考: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;
}