參照使用go編寫,基於epoll io復用模型,多協程同時監聽埠epoll,基於工作池,防止無限制協程個數
服務端:
select {}//阻塞
}func startepoll()
epoller, err := mkepoll()
if err != nil
go start(epoller)
for
log.printf("accept err :%v", e)
return
}log.printf("accept a conn")
if err := epoller.add(conn); err != nil
}}func start(epoller *epoll)
for _, conn := range connections
//_, err = io.copyn(conn, conn, 8)
//if err != nil
// conn.close()
//}"recv conn buf %s", string(buf))
var task ntask
task.conn = conn
task.epoller = epoller
workerpool.addtask(task)}}
}workerpool.go
package main
import (
"io"
"log"
"net"
"sync"
)type ntask struct
type pool struct
}func newpool(w int, t int) *pool ),
}}func (p *pool) close()
func (p *pool) addtask(task ntask)
p.mu.unlock()
p.taskqueue <- task
}func (p *pool) start()
}func (p *pool) startworker() }}
}func handleconn(task ntask)
task.conn.close()
}"read client data")
opsrate.mark(1)
}
epoll.go
package main
import (
"golang.org/x/sys/unix"
"log"
"net"
"reflect"
"sync"
"syscall"
)type epoll struct
func mkepoll() (*epoll, error)
return &epoll,
connections: make(map[int]net.conn),
},nil
}func (e *epoll) add(conn net.conn) error )
if err != nil
e.lock.lock()
defer e.lock.unlock()
e.connections[fd] = conn
if len(e.connections)%100 == 0
return nil
}func (e *epoll) remove(conn net.conn) error
e.lock.lock()
defer e.lock.unlock()
delete(e.connections, fd)
if len(e.connections)%100 == 0
return nil
}func (e *epoll) wait() (net.conn, error)
e.lock.rlock()
defer e.lock.runlock()
var connections net.conn
for i:=0; i < n; i++
return connections, nil
}//根據net.conn獲取實際的fd值
func socketfd(conn net.conn) int
客戶端:
clientepoll.go
//使用多個epoll
for i :=0; i < 4; i++
select {}//阻塞
}func mkclient(addr string, connections int)
var conns net.conn
for i := 0; i < connections; i++
if err := epoller.add(c); err != nil
}log.printf("init connections %d count", len(conns))
go start(epoller)
tts := time.second
if connections > 100
for i := 0; i < len(conns); i++ }}
}select {}
}func start(epoller *epoll)
for _, conn := range connections
if err := binary.read(conn, binary.bigendian, &nano); err != nil
conn.close()
continue
} else
err = binary.write(conn, binary.bigendian, time.now().unixnano())
if err != nil
conn.close()}}
}}
高併發伺服器(基於epoll)
本章節是用基本的linux unix基本函式編寫乙個完整的伺服器和客戶端例子,可在linux ubuntu 和unix freebsd 上執行,客戶端和服務端的功能如下 客戶端從標準輸入讀入一行,傳送到服務端 服務端從網路讀取一行,把小寫變為大寫,然後輸出到客戶端 客戶端收到服務端的響應,輸出這一行...
基於epoll的簡單高併發伺服器程式
epoll,select,poll都是基於linux unix的io復用技術。所謂io復用簡單來說就是讓核心來告知我們哪些檔案描述符讀或寫準備就緒。具體定義大家可以查閱各類書籍。epoll相對於select和poll來說對核心資源的利用更高效,因為select和poll是需要將帶有檔案描述符的資料結...
基於Redis Memcached的高併發秒殺設計
如何設計高併發時的秒殺,是面試電商技術職位時必考的題目。今天在這裡分享一下基於redis或memcached的技術方案,能解決重複提交 超發 高併發的問題。預定義總庫存 define total stock 5 預定義商品編號 define item id item 001 userid get u...