/*
*
*EPOLL ET 触发必须使用非阻塞,LT触发可以阻塞/非阻塞。
*read 函数 非阻塞读需 忙轮寻 soket关闭返回0,循环读完数据
*如果已经读完再读read返回 -1,errno=11(EAGIAN)则退出轮循
*
**/ #include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/select.h>
#include<sys/time.h>
#include<pthread.h>
#include<memory.h>
#include<errno.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<signal.h>
#include<semaphore.h>
#include<malloc.h>
#include<fcntl.h>
#include<sys/epoll.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define WKEY 100
#define RKEY 101
//#define DEBUG typedef unsigned int uint32; pthread_mutex_t lock;
uint32 qcount=; typedef struct{
int quenu;
sem_t sem;
}QUE_SEM; QUE_SEM rque ,wque; typedef struct{
int flag;
sem_t sem;
}MYLOCK; typedef struct{
long type;
char buff[];
}REQUEST; typedef struct{
long type;
int wrfd;
}RESPON; struct sockaddr_in server;
MYLOCK mlock;
int g_epfd=-; int rnum=;
int wnum=; void printerror()
{
printf("fun %s,%d num",__func__,__LINE__);
printf("rnum =%d ,wnum =%d\n",rnum,wnum);
printf("%d--->%s\n",errno,strerror(errno));
msgctl(rque.quenu,IPC_RMID,);
msgctl(wque.quenu,IPC_RMID,);
exit(-);
} void initREQUESTue(int rkey,int wkey){
int rq= msgget(rkey,IPC_CREAT|);
int wq= msgget(wkey,IPC_CREAT|);
sem_init(&rque.sem,,);
sem_init(&wque.sem,,);
rque.quenu=rq,wque.quenu=wq; printf("REQUEST r is %d ,w is %d\n",rq,wq);
} int ReadSocket(int fd){
REQUEST msg;
int rd=-;
memset(msg.buff,,sizeof (msg.buff));
msg.type=fd;
rd=read(fd,msg.buff,sizeof(msg.buff)-);
// printf("rd size is %d\n",rd);
if(rd==){
struct sockaddr_in client;
memset(&client,,sizeof(client));
int len=sizeof(client);
getpeername(fd,(struct sockaddr*)&client,&len);
// printf("client %s is closed fd is %d , bye!\n",inet_ntoa(client.sin_addr),fd);
close(fd);
return ;
}else if(rd>){
int res=-;
while(){
sem_wait(&rque.sem);
res =msgsnd(rque.quenu,&msg,sizeof(REQUEST)-sizeof(long),IPC_NOWAIT);
printf("read clietn and send to queue res=%d\n",res);
if(res==-){
printf("errno =%d msg=%s\n",errno,strerror(errno));
if(errno==ENOMEM){
sem_post(&rque.sem);
usleep();
continue;
}
sem_post(&rque.sem);
return ;
}else if(res==){
// printf("rnum=%d\n",rnum++);
sem_post(&rque.sem);
return ;
}
} }else if(rd==-){
close(fd);
return ;
}
} //int getMsgbyfd(int fd,REQUEST* msg){
// if(msgrcv(rque.quenu,msg,sizeof(REQUEST)-sizeof(long),fd,0)>0){
// return 1;
// }
// return 0;
//} void* th_procce(void* p){
while(){
sem_wait(&wque.sem);
RESPON msg;
#ifdef DEBUG
printf("proc thread ready to feth msg from wque\n");
#endif
int res=msgrcv(wque.quenu,&msg,sizeof(RESPON)-sizeof(long),,IPC_NOWAIT);
usleep();
#ifdef DEBUG
printf("proc feth msg from wque type=%d\n",res);
#endif
sem_post(&wque.sem);
usleep();
if(res>){
sem_wait(&rque.sem);
REQUEST req;
int res2=msgrcv(rque.quenu,&req,sizeof(REQUEST)-sizeof(long),msg.wrfd,IPC_NOWAIT);
#ifdef DEBUG
printf("proc feth msg from rque and send to client res=%d\n",res2);
#endif
if(res2>){
sem_post(&rque.sem);
char buff[]={};
sprintf(buff,"%s -> %s","Server Snd To",req.buff);
write(msg.wrfd,buff,strlen(buff));
}else if(res2==-&& errno==ENOMSG){
sem_post(&rque.sem);
continue;
}
usleep();
#ifdef DEBUG
printf("yet send to client\n");
#endif
}else if(res==-&& errno==ENOMSG){
continue;
}
}
} int sndtowque(int fd){
RESPON msg;
msg.type=fd;
msg.wrfd=fd;
while () {
sem_wait(&wque.sem);
int res=msgsnd(wque.quenu,&msg,sizeof(RESPON)-sizeof(long),IPC_NOWAIT);
// #ifdef DEBUG
printf("write event com and sendto wque res=%d\n",res);
// #endif
if(res==-){
if(errno==ENOMEM){
sem_post(&wque.sem);
usleep();
continue;
}
sem_post(&wque.sem);
return ;
}else if(res==){
printf("wnum-----=%d\n",wnum++);
sem_post(&wque.sem);
return ;
}
}
} void* th_hand(void* p){
sem_wait(&mlock.sem);
while(!mlock.flag){
sem_post(&mlock.sem);
sleep();
sem_wait(&mlock.sem);
}
sem_post(&mlock.sem);
struct epoll_event events[];
struct epoll_event event;
while(){
memset(&event,,sizeof(struct epoll_event));
memset(events,,sizeof(struct epoll_event)*);
int s = epoll_wait(g_epfd,events,,);
if(s==-){
printerror();
}else if(s==){
continue;
}else if(s>){
for(int i=;i<s;i++){
int fd=events[i].data.fd;
if(events[i].events & EPOLLIN){
if(ReadSocket(fd)){
events[i].events=EPOLLOUT|EPOLLET;
epoll_ctl(g_epfd,EPOLL_CTL_MOD,fd,&events[i]);
}else{
epoll_ctl(g_epfd,EPOLL_CTL_DEL,fd,);
continue;
}
}
if(events[i].events & EPOLLOUT){
if(sndtowque(fd)){
events[i].events=EPOLLIN|EPOLLET;
epoll_ctl(g_epfd,EPOLL_CTL_MOD,events[i].data.fd,&events[i]);
}else{
epoll_ctl(g_epfd,EPOLL_CTL_DEL,fd,);
continue;
}
}
}
}
}
} int initSocket(int port){
memset(&server,,sizeof(server));
server.sin_family=AF_INET;
server.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY==0
server.sin_port=htons(port);
int sockfd=socket(AF_INET,SOCK_STREAM,);
int flag=;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag));
if(sockfd==-){
printerror();
}
int res=bind(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr));
if(res==-){
printerror();
}
if(-==listen(sockfd,)){
printerror();
} g_epfd=epoll_create();
if(g_epfd==-){
printerror();
} sem_wait(&mlock.sem);
mlock.flag=;
sem_post(&mlock.sem); printf("main before accept\n");
while(){
int fd;
if((fd=accept(sockfd,NULL,NULL))==-){
printerror();
}
printf("fd %d is connect\n",fd);
struct epoll_event event;
// event.events=EPOLLIN;
event.events=EPOLLIN|EPOLLET;
event.data.fd=fd; fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,)|O_NONBLOCK); sem_wait(&mlock.sem);
if(-==(epoll_ctl(g_epfd,EPOLL_CTL_ADD,fd,&event))){
printerror();
}
qcount++;
sem_post(&mlock.sem);
}
} void sig_hand(int signo){
if(signo==SIGINT){
msgctl(rque.quenu,IPC_RMID,);
msgctl(wque.quenu,IPC_RMID,);
printf("have %d client\n",qcount);
exit();
}
} pthread_t pid;
pthread_t process;
int main(int argc,char** argv){
if(argc<){
puts("please input port\n");
exit(-);
}
initREQUESTue(RKEY,WKEY);
int port=atoi(argv[]);
signal(SIGINT,sig_hand);
memset(&mlock,,sizeof(mlock));
sem_init(&mlock.sem,,);
mlock.flag=; pthread_create(&pid,NULL,th_hand,(void*));
pthread_detach(pid); pthread_create(&process,NULL,th_procce,(void*));
pthread_detach(process);
initSocket(port); }

linux epoll 任务队列多线程模型的更多相关文章

  1. [源码分析] 分布式任务队列 Celery 多线程模型 之 子进程

    [源码分析] 分布式任务队列 Celery 多线程模型 之 子进程 目录 [源码分析] 分布式任务队列 Celery 多线程模型 之 子进程 0x00 摘要 0x01 前文回顾 1.1 基类作用 1. ...

  2. Java I/O演进与Linux网络I/O模型

    参考文章: 简书-浅谈Linux五种IO:http://www.jianshu.com/p/486b0965c296 一.linux基础概念 1.1 内存空间 linux系统中的使用的是虚拟存储器,即 ...

  3. Linux五种IO模型(同步 阻塞概念)

    Linux五种IO模型 同步和异步 这两个概念与消息的通知机制有关. 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.比如,调用readfrom系统调用时,必须等待IO操 ...

  4. Windows五种IO模型性能分析和Linux五种IO模型性能分析

    Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blo ...

  5. Linux 网络 I/O 模型简介(图文)

    1.介绍 Linux 的内核将所有外部设备都看做一个文件来操作(一切皆文件),对一个文件的读写操作会调用内核提供的系统命令,返回一个file descriptor(fd,文件描述符).而对一个sock ...

  6. Linux 网络 I/O 模型简介(图文)(转载)

    Linux 网络 I/O 模型简介(图文)(转载) 转载:http://blog.csdn.net/anxpp/article/details/51503329 1.介绍 Linux 的内核将所有外部 ...

  7. 框架篇:见识一下linux高性能网络IO+Reactor模型

    前言 网络I/O,可以理解为网络上的数据流.通常我们会基于socket与远端建立一条TCP或者UDP通道,然后进行读写.单个socket时,使用一个线程即可高效处理:然而如果是10K个socket连接 ...

  8. 追求性能极致:Redis6.0的多线程模型

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...

  9. Server Develop (六) Linux epoll总结

    Linux  epoll epoll是Kernel 2.6后新加入的事件机制,在高并发条件下,远优于select.epoll最大的好处在于它不会随着监听fd数目的增长而降低效率.因为在内核中的sele ...

随机推荐

  1. vue的开发中v-for报错 [vue/require-v-for-key] Elements in iteration expect to have 'v-bind:key' directives.

    用的VS Code 工具,安装了vetur插件,报错了如下 [eslint-plugin-vue] [vue/require-v-for-key] Elements in iteration expe ...

  2. 报错:Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2

    1.问题 写了一个简单的单层神经网络跑mnist手写数字集,结果每次fit都会出现dead kernel 很多dead kernel首先不要急着去网上搜dead kernel怎么解决,因为大家出现的原 ...

  3. POJ 1469:COURSES

    COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19458   Accepted: 7658 Descript ...

  4. POJ 1035:Spell checker

    Spell checker Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 22574   Accepted: 8231 De ...

  5. Zookeeper--Zookeeper单机安装

    参考 https://www.cnblogs.com/lsdb/p/7297731.html https://zookeeper.apache.org/doc/r3.4.13/zookeeperSta ...

  6. 新iPhone的高售价下,苹果供应商们是该笑还是该哭?

    自新 iPhone发布之日起,世界就从未停止讨论其售价,越来越多的人开始困惑:新 iPhone毫无创新亮点,有什么底气卖到12799RMB呢?整个地球都在期待苹果推出廉价版 iPhone,望眼欲穿地等 ...

  7. 阿里巴巴的26款Java开源项目,赶紧戳…

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  8. TCP连接为什么三次握手四次挥手

    前几天面试某电商被问住了,问的很细,我就说了说连接过程,必然凉凉.在csdn上找了一篇很详细的博客.https://blog.csdn.net/hyg0811/article/details/1023 ...

  9. pycharm2018专业版

    https://blog.csdn.net/moshanghuali/article/details/94396935 1 下载Pycharm专业版2018.3.1许多人直接在官网直接下载,默认的都是 ...

  10. 24.docker 部署 wordPress

    1. 拉取远程 mysql 和 wordpress 镜像 并 启动起来 使用 docker pull mysql:5.7.27 docker pull wordpress 2. 创建mysql 的 c ...