/*
*
*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. k8s deployment yam 文件分析

    apiVersion: extensions/v1beta1 kind: Deployment metadata: name: namespace: labels:spec: replicas: #设 ...

  2. hdfs 删除和新增节点

    最近发现hdfs的一个问题,每当集群开启的时候,有一个节点上的可用空间就一直在减少,并且速度很快,发现是data目录下的dncp_block_verification.log.curr文件在一直变大, ...

  3. my97datepicker实现日期改变立刻触发函数

    <input type="text" class="Wdate" onclick="WdatePicker({onpicking:functio ...

  4. hdu 1799 循环多少次?(组合)

    题目是这样的:   我们知道,在编程中,我们时常需要考虑到时间复杂度,特别是对于循环的部分.例如, 如果代码中出现 for(i=1;i<=n;i++) OP ; 那么做了n次OP运算,如果代码中 ...

  5. grep 使用方法 --rn使用

    生产环境中,我们经常会碰到一个报错但是却不知道配置文件的路径在哪里,这时候用rn就能轻松解决 [root@localhost ~]# grep -rn "搜索的内容" 路径

  6. IE8Get请求中文不兼容:encodeURI的使用

    IE8Get请求中文不兼容:encodeURI的使用 在开发过程中遇到在IE8下,请求出错. 后发现Get请求中含有中文字符. 使用js自带的encodeURI函数对中文进行编码,问题解决. enco ...

  7. App基本界面组件案例

    今天的收获颇大呀,我发现了一个更高效快速的学习方法,如果真的是因为学习内容太多,无从下手的话,不妨去别人或者自己崇拜的大佬里的博客园里面转一转,你就会有意外的收获,不仅给你学习的压力,还更直观的给介绍 ...

  8. Dlib笔记一:基本数据结构和基本操作

    编译了Dlib之后就开始想着怎么用起来,先从基本的数据类型说起吧,因为是图像,所以难免会跟OpenCV的数据类型比较.在Dlib中,图像是用二维阵列(array2d)或者矩阵(matrix)来表示的, ...

  9. 流程引擎表单引擎的常见问题技术交流-关于广州xx公司对驰骋BPM提出

    第1章: 先使用.net 再使用java,数据迁移问题?会存在哪些问题. RE: .net 版本的ccflow与java版本的jflow系列版本都是一个数据库结构,一个操作手册,流程模版,表单模版通用 ...

  10. 开源PLM软件Aras详解八 Aras之RelationshipTypes关系类详解

    在Aras中,在之前ItemType解析中有提到,Aras中实际ItemType对应的就是一张表,那么,ItemType与ItemType之间是如何关联的呢, 如果我们需要捋清楚ItemType与It ...