/*
*
*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. The hierarchy of the type is inconsistent

    原因:我看到有一个interface的java类里面import了一个没有用到的类,手贱,把这个接口里面引用了但是没有没有用到的类删掉了, 结果这个接口的子类用到了,统统报标题上的错误.只要把删掉的改 ...

  2. PWC6199:Generated servlet error:Only a type can be imported. org.apache.jasper.tagplugins.jstl.core.ForEach resolves to a package

    <%@ import="org.apache.jasper.tagplugins.jstl.core.ForEach"%> 去掉这条语句,就不报错了.所以问题就出在这里 ...

  3. 刷题之Implement strStr()、Climbing Stairs

    public class Solution { public int strStr(String haystack, String needle) { int big = haystack.lengt ...

  4. Java平台上的AOP实现机制

    Java平台上的AOP实现机制 动态代理(Dynamic Proxy)机制,在运行期间动态的为相应接口生成对应的代理对象.SpringAop默认情况下采用这种机制来实现AOP机能.缺点:相对于编译后的 ...

  5. 一小时搞定Eureka

    一.什么是Eureka Eureka是Netflix公司开源的产品,它是一种基于REST( Representational State Transfer )的服务,主要用于AWS云. Eureka提 ...

  6. 低JAVA版本,高兼容性启动

    低JAVA版本,高兼容性启动 背景:部分操作系统java环境低版本,暂时无法更新最新版本,新系统需要使用较高版本Java环境 1.JAVA低版本不兼容当前应用 2.解压安装JAVA,无需配置环境变量 ...

  7. Nginx之epoll和select poll

    epoll和 select poll 都是做I/O多路复用的. 区别在于: epoll较灵活,如果有一百万个链接状态同时保持,但是在某个时刻,只有几百个链接是活跃的.epoll的处理是通过epoll_ ...

  8. react动态生成列表

    在组件的render函数中遍历数组menus[]并且要return返回虚拟Dom对象. render() { return createPortal( this.state.visible & ...

  9. 网格视图GridView

    1.常用属性 2.Adapter接口 3.Demo演示 今天观看了GridView的相关视频,并且根据案例,进行了代码的编写和实例 新建GridViewActivity.java继承AppCompat ...

  10. 并发与高并发(十三)J.U.C之AQS

    前言 什么是AQS,是AbstractQueuedSynchronizer类的简称.J.U.C大大提高了并发的性能,而AQS又是J.U.S的核心. 主体概要 J.U.C之AQS介绍 J.U.C之AQS ...