c/c++ llinux epoll系列5 解除epoll_wait状态

linux epoll系列5 解除epoll_wait状态

有时候会有解除epoll_wait状态的需求。

实现方法:

1,给执行epoll_wait的程序发signal。

2,使用sockpair。

1,给执行epoll_wait的程序发signal。

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/epoll.h>

void sigusr1_handler(int sig){
  write(fileno(stdout), "signal called\n", 14);
}

int main(){
  int nfds;
  int epfd;

  signal(SIGUSR1, sigusr1_handler);

  epfd = epoll_create(1);
  if(epfd < 0){
    perror("epoll_crreate");
    return 1;
  }

  printf("before epoll_wait\n");

  //一直等下去
  nfds = epoll_wait(epfd, NULL, 1, -1);
  printf("after epoll_wait:%d\n", nfds);

  printf("%d\n", errno);
  perror("perror after epoll_wait");

  return 0;
}

github源代码

执行方法:

1,执行程序

2,先用下面的命令找到当前执行程序的PID

ps -e | grep a.out

结果:

[email protected]:~/cpp/network$ ps -e | grep a.out
 2882 pts/0    00:00:00 a.out

3,给个执行中的程序发signal

kill -s SIGUSR1 2882

结果:

before epoll_wait
signal called
after epoll_wait:-1
4
perror after epoll_wait: Interrupted system call

2,使用sockpair。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>

#define EVENTS 8

int soc[2];

void processA(){
  sleep(3);
  printf("processA: send message\n");
  write(soc[0], "HELLO\n", 6);
  return;
}

void processB(){
  int epfd;
  epoll_event ev, ev_ret[EVENTS];
  int nfds;
  int i;
  char buf[128];

  epfd = epoll_create(1);
  if(epfd < 0){
    perror("epoll_create");
    return ;
  }

  memset(&ev, 0, sizeof(ev));
  ev.events = EPOLLIN;
  ev.data.fd = soc[1];

  if(epoll_ctl(epfd, EPOLL_CTL_ADD, soc[1], &ev) != 0){
    perror("epoll_clt");
    return ;
  }

  memset(&ev, 0, sizeof(ev));
  ev.events = EPOLLIN;
  ev.data.fd = fileno(stdin);

  if(epoll_ctl(epfd, EPOLL_CTL_ADD, fileno(stdin), &ev) != 0){
    perror("epoll_clt1");
    return ;
  }

  while(1){
    printf("before epoll_wait\n");

    nfds = epoll_wait(epfd, ev_ret, EVENTS , -1);
    if(nfds < 0){
      perror("epoll_wait");
      return;
    }

    printf("after epoll_wait\n");

    for(i = 0; i < nfds; ++i){
      if(ev_ret[i].data.fd == soc[1]){
    printf("processB:break message from socketpair\n");
    goto outofloop;
      }
      else if(ev_ret[i].data.fd == fileno(stdin)){
    read(fileno(stdin), buf, sizeof(buf));
    printf("processB:input from stdin\n");
      }
    }
  }

 outofloop:
  printf("process B:outside of loop\n");

  return ;
}
int main(){
  int ret;

  ret = socketpair(AF_UNIX, SOCK_STREAM, 0, soc);
  if(ret != 0){
    perror("socketpair");
    return 1;
  }

  if(fork() == 0){
    processA();
  }
  else{
    processB();
  }

  return 0;
}

github源代码

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

原文地址:https://www.cnblogs.com/xiaoshiwang/p/9827592.html

时间: 2024-08-30 04:48:18

c/c++ llinux epoll系列5 解除epoll_wait状态的相关文章

c/c++ llinux epoll系列4 利用epoll_wait实现非阻塞的connect

llinux epoll系列4 利用epoll_wait实现非阻塞的connect connect函数是阻塞的,而且不能设置connect函数的timeout时间,所以一旦阻塞太长时间,影响用户的体验,所以就出来一个需求,硬要设置connect的timeout时间. 实现方法:先把connect函数变成非阻塞的,然后用设置epoll_wait的timeout时间,用epoll_wait等待connect的完成. #include <stdio.h> #include <unistd.h&

c/c++ linux epoll系列3 利用epoll_wait设置timeout时间长度

linux epoll系列3 利用epoll_wait设置timeout时间长度 epoll_wait函数的第四个参数可以设置,epoll_wait函数的等待时间(timeout时间长度). 例子1,是接收端. 例子2,是发送端. 例子1,接收端 #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h

c/c++ linux epoll系列1 创建epoll

linux epoll系列1 创建epoll 据说select和poll的弱点是,随着连接(socket)的增加,性能会直线下降. epoll不会随着连接(socket)的增加,性能直线下降. 知识点: 1,epoll_wait函数是阻塞的,直到有socket发生变化. 2,epoll使用流程,先创建(epoll_create),再把socket添加到epoll里(epoll_ctl),然后等待socket的变化(epoll_wait) 接收端,接收2个socket #include <stdi

HTTP知识普及系列:HTTP返回状态码

状态码 1XX 信息性状态码 接受的请求正在处理 2XX 成功状态码 请求正常处理完毕 3XX 重定向状态码 需要进行附加操作以完成请求 4XX 客户端错误状态码 服务器无法处理请求 5XX 服务器端错误状态码 服务器处理请求出错 2XX 相应结果表明请求被正常处理了 200 OK 表示从客户端发来的请求在服务器端被正常处理了: 204 No Content 该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分.也不允许返回任何实体的主体. 206 Partial Co

python实战系列之MySQL主从状态监控(09)

1. 需求说明 由于openstack底层中MySQL使用了主从AB复制,为了监控数据库的主从状态信息,需要对MySQL的主从状态进行监控,从而保障数据库底层正常运行,为openstack提供更好的功能.本文对数据库执行监控,具体内容参考下面. 2. 程序内容 #!/usr/bin/env python #_*_ coding:utf8 _*_ #author:happyliu #用于监控MySQL主从复制状态 import os import sys import os.path import

React系列文章:无状态组件生成真实DOM结点

在上一篇文章中,我们总结并模拟了JSX生成真实DOM结点的过程,今天接着来介绍一下无状态组件的生成过程. 先以下面一段简单的代码举例: const Greeting = function ({name}) { return <div>{`hello ${name}`}</div>; }; const App = <Greeting name="scott"/>; console.log(App); ReactDOM.render(App, docum

linux timerfd系列函数总结

网上关于timerfd的文章很多,在这儿归纳总结一下方便以后使用,顺便贴出一个timerfd配合epoll使用的简单例子 一.timerfd系列函数 timerfd是Linux为用户程序提供的一个定时器接口.这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,因此可以配合select/poll/epoll等使用. 下面对timerfd系列函数先做一个简单的介绍: (1)timerfd_create()函数 #include <sys/timerfd.h> int timerfd_cr

基本I/O模型与Epoll简介

5种基本的I/O模型:1)阻塞I/O ;2)非阻塞I/O; 3)I/O复用(select和poll);4)信号驱动I/O(SIGIO);5)异步I/O(POSIX.1的aio_系列函数). 操作系统中一个输入操作一般有两个不同的阶段: 第一:等待数据准备好.第二:从内核到进程拷贝数据.对于一个sockt上的输入操作,第一步一般是等待数据到达网络,当分组到达时,它被拷贝到内核中的某个缓冲区,第二步是将数据从内核缓冲区拷贝到应用程序缓冲区. 一.           阻塞I/O模型 请求无法立即完成

用C写一个web服务器(二) I/O多路复用之epoll

.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .container::before,.container::after { content: " "; display: table } .container::after { clear: both } .container::before,.container::after { content: