W. Richard Stevens UNIX Sockets API echo Sockets TCP OOB IO C struct C/C++ UNIX fork() select(2)/poll(2)/epoll(4) IO IO CPU 100% libevent IO UNIX CPU
|
|
|
- 钉 红
- 7 years ago
- Views:
Transcription
1 Linux muduo C++ C++ TCP C++ x86-64 Linux TCP one loop per thread Linux native muduo C++ IT 5 C++ muduo 2 C++ C++ Primer 4
2 W. Richard Stevens UNIX Sockets API echo Sockets TCP OOB IO C struct C/C++ UNIX fork() select(2)/poll(2)/epoll(4) IO IO CPU 100% libevent IO UNIX CPU IO UNIX 2 IPC 7 24 C++ STL C++ Linux muduo C++
3 C++ x86-64 Linux TCP 5 IO one loop per thread Linux native muduo muduo IO C++ one loop per thread IO muduo Linux A C++ C TR1 C++ C++ C C++ UNIX UNIX C++ Primer Pthreads Sockets API C Linux g C++11 x86-64 CPU GB 5 IO 1 C++ C++ 2 muduo muduo 3 C++ 4 C++ UDP iii
4 iv Observer Reactor Singleton class heap event loop STL algorithm C++ instance resolution instantiation override dereference class 6 syscall (s) fd file descriptor CPU core kb MB GB KiB MiB GiB L42 42 [JCP] [CC2e] mutex socket C++ class this mutable class fork(2) muduo::eventloop fork(2) fork() manpage 2 man 2 fork - EventLoop- ThreadPool URL muduo/base/date.h GitHub chenshuo/recipes/ recipes/thread GitHub URL muduo/base/types.h 1 muduo::string typedef 15 namespace muduo 16 { #ifdef MUDUO_STD_STRING 19 using std::string; 20 #else //!MUDUO_STD_STRING 21 typedef gnu_cxx:: sso_string string; 22 #endif muduo/base/types.h muduo/base/types.h muduo muduo/examples/xxx examples/xxx 8 recipes/reactor/xxx reactor/xxx
5 v diff -u URL
6 1 C C muduo muduo muduo muduo C C C A B C++ Primer 4 C C Boost D TCP vi
7 1 C MutexLock MutexLockGuard Counter mutex mutex Observer shared_ptr/weak_ptr Observer shared_ptr shared_ptr enable_shared_from_this Observer mutex vii
8 viii mutex condition variable MutexLock MutexLockGuard Condition Singleton sleep(3) shared_ptr copy-on-write one loop per thread TCP C C/C Linux pthread_cancel C exit(3) C thread IO
9 ix 4.7 RAII RAII fork() fork() signal Linux muduo muduo TCP echo finger muduo Boost.Asio libevent muduo libevent muduo Nginx muduo ZeroMQ muduo
10 x 7 muduo TCP Boost.Asio TCP LengthHeaderCodec muduo Buffer muduo IO non-blocking buffer Buffer Buffer Buffer Google Protobuf Protobuf type name Message Protobuf muduo Protobuf codec ProtobufCodec dispatcher ProtobufCodec ProtobufDispatcher ProtobufDispatcher ProtobufCodec ProtobufDispatcher muduo
11 xi Linux muduo Boost.Asio Timer Java Netty timing wheel timing wheel socks4a TCP socks4a N : 1 1 : N UDNS c-ares DNS curl muduo EventLoop Reactor Channel class Poller class EventLoop TimerQueue TimerQueue class EventLoop
12 xii 8.3 EventLoop::runInLoop() TimerQueue EventLoopThread class TCP TcpServer TcpServer class TcpConnection class TcpConnection Buffer TcpConnection Buffer Buffer::readFd() TcpConnection TcpConnection SIGPIPE TCP No Delay TCP keepalive WriteCompleteCallback HighWaterMarkCallback TcpServer Connector TcpClient epoll
13 xiii TCP ICE naming service C C C C C C++ linking inline
14 xiv C C ABI COM C Linux COM Java boost::function boost::bind iostream stdio iostream iostream
15 xv iostream iostream memory buffer output stream C++ IO C C ::operator new() ::operator new() ::operator new() ::operator new() malloc() class ::operator new() C/C
16 xvi 12.4 mock link seam namespace C static C++ static namespace diff grep std::string eager copy copy-on-write SSO STL algorithm next_permutation() unique() {make,push,pop}_heap() partition() lower_bound() IP A 561 B C++ Primer 4 C C Boost 591 D TCP
17 1 C++
18
19 1 synchronization primitives mutex race condition C++ Boost shared_ptr weak_ptr 1 Observer C++ C++ Observer 1.1 C++ race condition race condition C++ shared_ptr C++ 1 class TR1 std::tr1 C++11 3
20 [JCP] class interleaving C++ class std:: string std::vector std::map class MutexLock MutexLockGuard C MutexLock critical section RAII [CCS 13] Windows struct CRITI- CAL_SECTION Linux pthread_mutex_t 2 MutexLock class MutexLockGuard MutexLockGuard class Counter class Counter 1 // A thread-safe counter 2 class Counter : boost::noncopyable 3 { 4 // copy-ctor and assignment should be private by default for a class. 5 public: 6 Counter() : value_(0) {}
21 int64_t value() const; 8 int64_t getandincrease(); 9 10 private: 11 int64_t value_; 12 mutable MutexLock mutex_; 13 }; int64_t Counter::value() const 16 { 17 MutexLockGuard lock(mutex_); // lock 18 return value_; // 19 } int64_t Counter::getAndIncrease() 22 { 23 MutexLockGuard lock(mutex_); 24 int64_t ret = value_++; 25 return ret; 26 } 27 // In a real world, atomic operations are preferred. 28 // class class Counter mutex_ lock contention L24 Counter mutex_ mutable const Counter::value() non-const mutex_ mutex_ static / Counter Counter race condition 1.2 this this this escape
22 6 1 // Don't do this. class Foo : public Observer // Observer 10 { public: Foo(Observable* s) { s->register_(this); // } virtual void update(); }; // Do this. class Foo : public Observer { public: Foo(); virtual void update(); // void observe(observable* s) { s->register_(this); } }; Foo* pfoo = new Foo; Observable* s = getsubject(); pfoo->observe(s); // s->register_(pfoo); +initialize() C++ initialize() this Foo Foo::Foo() most-derived class
23 mutex mutex mutex (1) (2) Foo::~Foo() { MutexLockGuard lock(mutex_); // free internal state (1) } void Foo::update() { MutexLockGuard lock(mutex_); // (2) // make use of internal state } A B Foo x A x B x->update() extern Foo* x; // visible by all threads // thread A delete x; x = NULL; // helpless // thread B if (x) { x->update(); } A NULL B x x race condition 1. A (1) 2. B if (x) (2) mutex_ (2) core dump delete NULL 3 dangling pointer wild pointer
24 mutex class MutexLock class MutexLock MutexLock 1.1 class swap() void swap(counter& a, Counter& b) { MutexLockGuard alock(a.mutex_); MutexLockGuard block(b.mutex_); int64_t value = a.value_; a.value_ = b.value_; b.value_ = value; } // potential dead lock A swap(a, b); B swap(b, a); operator=() Counter& Counter::operator=(const Counter& rhs) { if (this == &rhs) return *this; } MutexLockGuard mylock(mutex_); // potential dead lock MutexLockGuard itslock(rhs.mutex_); value_ = rhs.value_; // value_ = rhs.value() return *this; mutex mutex 1.4 Observer
25 1.4 Observer 9 [CCS 99] free(3) C/C++ 4 composition aggregation association composition / x owner owner x x owner scoped_ptr owner C++ association / a b a b b a aggregation association a b b 1.1 A x B x lock contention x x race condition 4 Java reference null
26 10 1 Observer recipes/thread/test/observer.cc 1 class Observer // : boost::noncopyable 2 { 3 public: 4 virtual ~Observer(); 5 virtual void update() = 0; 6 //... 7 }; 8 9 class Observable // : boost::noncopyable 10 { 11 public: 12 void register_(observer* x); 13 void unregister(observer* x); void notifyobservers() { 16 for (Observer* x : observers_) { // C x->update(); // (3) 18 } 19 } 20 private: 21 std::vector<observer*> observers_; 22 }; Observable Observer (L17) Observer x Observer unregister() 23 class Observer 24 { 25 // 26 void observe(observable* s) { 27 s->register_(this); 28 subject_ = s; 29 } virtual ~Observer() { 32 subject_->unregister(this); 33 } Observable* subject_; 36 }; Observer unregister(this) race conditions L32 subject_ subject_ 1. A L32 unregister 2. B L17 x L32
27 x Observer 5 Observer L32 core dump race condition isalive() 1.5 raw pointer Observable Observer* Observer Observer race condition subject_ Observable* C++ shared_ptr p1 p2 Object p1 p2 1-1 A p1 p1 NULL p2 1-1 C/C++ p1 p2 Object p1=0 p2 Object C++
28 12 1 p1 p2 1-2 proxy Object C p1 p2 p1 proxy Object p2 1-2 Object proxy p2 proxy Object p1=0 proxy=0 Object p2 1-3 Object race condition p2 proxy Object p1 proxy proxy reference counting p1 p2 sp1 sp2 proxy sp1 sp2 pointer count = Object
29 1.6 shared_ptr/weak_ptr sp sp1 sp2 pointer count = Object 3. sp2 0 proxy Object 1-6 sp1 sp2 pointer count = Object another layer of indirection 6 Object handle/body idiom handle 7 C++ TR1 1.6 shared_ptr/weak_ptr shared_ptr Boost std::tr1 C++11 C++ shared_ptr<t> class template Edsger W. Dijkstra The Humble Programmer
30 weak_ptr weak shared_ptr shared_ptr shared_ptr x shared_ptr x x shared_ptr reset() x weak_ptr promote shared_ptr shared_ptr /lock() shared_ptr/weak_ptr shared_ptr/weak_ptr std::string STL 8 C++ clean up C Nginx C 10 C C Java C
31 C++ 1. buffer overrun 2. / 3. double delete 4. memory leak 5. new[]/delete 6. memory fragmentation A std::vector<char>/std::string Buffer class 2. / shared_ptr/weak_ptr 3. scoped_ptr 4. scoped_ptr 5. new[]/delete new[] std::vector/scoped_array std:: vector/std::list std::string C++ delete security data safety scoped_ptr/shared_ptr/weak_ptr shared_ptr<foo>* pfoo = new shared_ptr<foo>(new Foo); // WRONG semantic x T incomplete x.cpp
32 Observer weak_ptr Observer Observable weak_ptr<observer> recipes/thread/test/observer_safe.cc 39 class Observable // not 100% thread safe! 40 { 41 public: 42 void register_(weak_ptr<observer> x); // const weak_ptr<observer>& 43 // void unregister(weak_ptr<observer> x); // 44 void notifyobservers(); private: 47 mutable MutexLock mutex_; 48 std::vector<weak_ptr<observer> > observers_; 49 typedef std::vector<weak_ptr<observer> >::iterator Iterator; 50 }; void Observable::notifyObservers() 53 { 54 MutexLockGuard lock(mutex_); 55 Iterator it = observers_.begin(); // Iterator while (it!= observers_.end()) 57 { 58 shared_ptr<observer> obj(it->lock()); // 59 if (obj) 60 { 61 // 2 62 obj->update(); // obj 63 ++it; 64 } 65 else 66 { 67 // weak_ptr 68 it = observers_.erase(it); 69 } 70 } 71 } recipes/thread/test/observer_safe.cc (3) p. 10 L17 L48 vector<shared_ptr<observer> > observers_; Observer* weak_ptr<observer> Observer 1.14
33 1.9 shared_ptr 17 Observer shared_ptr Observer subject_->unregister(this) subject_ Observable shared_ptr subject_ weak_ptr<observable> lock contention Observable register_() unregister() notifyobservers() update() register_() unregister() L62 update() (un)register mutex_ mutex_ core dump vector observers_ mutex_ std::list ++it mutex Pthreads mutex Java intrinsic lock synchronized synchronized 1.9 shared_ptr shared_ptr shared_ptr 100% shared_ptr 11 shared_ptr std::string shared_ptr 1 shared_ptr 2 shared_ptr 3~5 shared_ptr 11
34 18 1 shared_ptr mutex MutexLock mutex; // ReadersWriterLock SpinLock shared_ptr<foo> globalptr; // globalptr doit() void doit(const shared_ptr<foo>& pfoo); globalptr race condition globalptr void read() { shared_ptr<foo> localptr; { MutexLockGuard lock(mutex); localptr = globalptr; // read globalptr } // use localptr since here localptr doit(localptr); } void write() { shared_ptr<foo> newptr(new Foo); // { MutexLockGuard lock(mutex); globalptr = newptr; // write to globalptr } // use newptr since here newptr doit(newptr); } read() write() globalptr Foo shared_ptr local copy local copy shared_ptr reference to const new Foo globalptr.reset(new Foo) globalptr.reset() localptr globalptr swap() write() globalptr = newptr; globalptr Foo
35 1.10 shared_ptr shared_ptr shared_ptr x shared_ptr shared_ptr p. 16 L48 observers_ vector<shared_ ptr<observer> > unregister() Observer unregister() unregister() Observer Java boost::bind boost::bind shared_ptr boost::function class Foo { void doit(); }; shared_ptr<foo> pfoo(new Foo); boost::function<void()> func = boost::bind(&foo::doit, pfoo); // long life foo func shared_ptr<foo> Foo shared_ptr const reference const reference shared_ptr Foo void save(const shared_ptr<foo>& pfoo); void validateaccount(const Foo& foo); bool validate(const shared_ptr<foo>& pfoo) { validateaccount(*pfoo); //... } // pass by const reference // pass by const reference pass by const reference void onmessage(const string& msg) { shared_ptr<foo> pfoo(new Foo(msg)); // if (validate(pfoo)) { // pfoo save(pfoo); // pfoo } }
36 20 1 shared_ptr pfoo shared_ptr<void> shared_ptr DLL A B Foo Foo inline Foo Factory shared_ptr shared_ptr<t> functor Scott Meyers 12 x shared_ptr x shared_ptr BlockingQueue<shared_ptr<void> > RAII handle RAII C++ RAII C++ C++ C++ new delete new delete RAII [CCS 13] new handle shared_ptr delete shared_ptr owner child shared_ptr child owner weak_ptr 12
37 Stock Google key "NASDAQ:GOOG" IBM "NYSE:IBM" Stock Stock Stock Stock StockFactory 13 key Stock shared_ptr // version 1: questionable code class StockFactory : boost::noncopyable { public: shared_ptr<stock> get(const string& key); private: mutable MutexLock mutex_; std::map<string, shared_ptr<stock> > stocks_; }; get() stocks_ key stocks_[key] Stock stocks_[key] Stock map shared_ptr Observable weak_ptr // version 2: std::map<string, weak_ptr<stock> > stocks_; shared_ptr<stock> StockFactory::get(const string& key) { shared_ptr<stock> pstock; MutexLockGuard lock(mutex_); weak_ptr<stock>& wkstock = stocks_[key]; // key pstock = wkstock.lock(); // if (!pstock) { pstock.reset(new Stock(key)); wkstock = pstock; // stocks_[key] wkstock } return pstock; } 13 recipes/thread/test/factory.cc
38 22 1 Stock stocks_ stocks_.size() Stock Stock 0 key shared_ptr shared_ptr d d(ptr) ptr shared_ptr shared_ptr bridge template<class Y, class D> shared_ptr::shared_ptr(y* p, D d); template<class Y, class D> void shared_ptr::reset(y* p, D d); // Y T Y* T* Stock stocks_ // version 3 class StockFactory : boost::noncopyable { // get() pstock.reset(new Stock(key)); // pstock.reset(new Stock(key), // boost::bind(&stockfactory::deletestock, this, _1)); // *** private: void deletestock(stock* stock) { if (stock) { MutexLockGuard lock(mutex_); stocks_.erase(stock->key()); } delete stock; // sorry, I lied } // assuming StockFactory lives longer than all Stock's... //... pstock.reset() boost::function Stock* p StockFactory deletestock StockFactory this boost::function *** Stock- Factory Stock core dump Observer Observable::unregister() Observable
39 enable_shared_from_this StockFactory::get() this boost::function *** StockFactory Stock Stock StockFactory::deleteStock core dump shared_ptr StockFactory::get() shared_ptr<stockfactory> enable_shared_from_this 14 this shared_ptr class StockFactory : public boost::enable_shared_from_this<stockfactory>, boost::noncopyable { /*... */ }; shared_from_this() StockFactory stack object heap object shared_ptr shared_ptr<stockfactory> stockfactory(new StockFactory); this shared_ptr<stockfactory> // version 4 shared_ptr<stock> StockFactory::get(const string& key) { // change // pstock.reset(new Stock(key), // boost::bind(&stockfactory::deletestock, this, _1)); // to pstock.reset(new Stock(key), boost::bind(&stockfactory::deletestock, shared_from_this(), _1)); //... boost::function shared_ptr<stockfactory> StockFactory::deleteStock StockFactory shared_from_this() StockFactory shared_ptr StockFactory 14
40 shared_ptr boost::bind boost:function Stock- Factory boost:function Observable::notifyObservers() weak_ptr weak_ptr boost::function shared_ptr StockFactory class StockFactory : public boost::enable_shared_from_this<stockfactory>, boost::noncopyable { public: shared_ptr<stock> get(const string& key) { shared_ptr<stock> pstock; MutexLockGuard lock(mutex_); weak_ptr<stock>& wkstock = stocks_[key]; // wkstock pstock = wkstock.lock(); if (!pstock) { pstock.reset(new Stock(key), boost::bind(&stockfactory::weakdeletecallback, boost::weak_ptr<stockfactory>(shared_from_this()), _1)); // shared_from_this() weak_ptr // boost::bind wkstock = pstock; } return pstock; } private: static void weakdeletecallback(const boost::weak_ptr<stockfactory>& wkfactory, Stock* stock) { shared_ptr<stockfactory> factory(wkfactory.lock()); // if (factory) // factory stocks_ { factory->removestock(stock); } delete stock; // sorry, I lied }
41 void removestock(stock* stock) { if (stock) { MutexLockGuard lock(mutex_); stocks_.erase(stock->key()); } } private: mutable MutexLock mutex_; std::map<string, weak_ptr<stock> > stocks_; }; void testlonglifefactory() { shared_ptr<stockfactory> factory(new StockFactory); { shared_ptr<stock> stock = factory->get("nyse:ibm"); shared_ptr<stock> stock2 = factory->get("nyse:ibm"); assert(stock == stock2); // stock destructs here } // factory destructs here } void testshortlifefactory() { shared_ptr<stock> stock; { shared_ptr<stockfactory> factory(new StockFactory); stock = factory->get("nyse:ibm"); shared_ptr<stock> stock2 = factory->get("nyse:ibm"); assert(stock == stock2); // factory destructs here } // stock destructs here } Stock StockFactory shared_ptr weak_ptr Factory singleton 15 StockFactory Stock stocks_ recipes/thread/weakcallback.h C++11 variadic template rvalue reference
42 shared_ptr/weak_ptr C++ 1. façade Foo Foo façade objid/handle check-out check-in 16 race condition façade Foo Java ConcurrentHashMap buckets bucket contention shared_ptr shared_ptr 4. C++11 unique_ptr shared_ptr Google Go Concurrency is hard without garbage collection C/C++ Java util.concurrent C API 16 Jeff Grossman A technique for safe deletion with object locking [Gr00] 17
43 shared_ptr C++ C Java Java Concurrency in Practice [JCP] C++ Java IPC race condition CPU CPU CPU CPU ilovecpp race condition shared_ptr/scoped_ptr 18 50% Google
44 28 1 shared_ptr boost::bind shared_ptr weak_ptr shared_ptr boost::shared_ptr C++11 unique_ptr auto_ptr shared_ptr TR1 C++ 19 C++ STL shared_ptr std::vector shared_ptr / 1.14 Observer 1.8 shared_ptr/weak_ptr Observer Observer Observer OO Observer Observer friend Observer Observer class Foo 1 30 work around Base class 19 C++ new delete memory leak C++ smart pointer STL Boost ( ) 4 smart pointers C++ memory leak!
45 1.14 Observer 29 Observer Java Java 8 Closure C# delegate C++ boost::function/ boost::bind 20 C++ Observer Signal/Slots QT thread safe race condition free thread contention free Signal/Slots shared_ptr 1.8 Observer 2.8 shared_ptr copy-on-write C++11 variadic template trivial template<typename Signature> class SignalTrivial; recipes/thread/signalslottrivial.h // NOT thread safe!!! template <typename RET, typename... ARGS> class SignalTrivial<RET(ARGS...)> { public: typedef std::function<void (ARGS...)> Functor; void connect(functor&& func) { functors_.push_back(std::forward<functor>(func)); } void call(args&&... args) { for (const Functor& f: functors_) { f(args...); } } private: std::vector<functor> functors_; }; recipes/thread/signalslottrivial.h Signal/Slots Slot unregister recipes/thread/signalslot.h boost::function boost::bind function/bind
46 30 1 C++ Ruminations on C++ Koenig Moo 2003 C++ 6 C++ handle/body idiom C++ shared_ptr C++ auto_ptr C++ shared_ptr C STL 10 STL vector 21
47 2 muduo
48
49 6 muduo ACE 1 Linux Windows x86-64 IA32 muduo ARM UDP TCP IPv6 IPv4 muduo IO + one event loop per thread IO API API non-trivial templates 90% app lib library framework 5000 FreeBSD/Darwin Mac IO multiplexing poll(2) epoll(4) Google Protocol Buffers RPC
50 126 6 muduo C++ muduo 2 Google code muduo git muduo Sockets API Python Hello hello-server.py 1 #!/usr/bin/python 2 3 import socket, time 4 5 serversocket = socket.socket(socket.af_inet, socket.sock_stream) 6 serversocket.bind(('', 8888)) 7 serversocket.listen(5) 8 9 while True: 10 (clientsocket, address) = serversocket.accept() # 11 data = clientsocket.recv(4096) # 12 datetime = time.asctime()+'\n' 13 clientsocket.send('hello ' + data) # 14 clientsocket.send('my time is ' + datetime) # 15 clientsocket.close() # hello-server.py 20 # import 21 sock = socket.socket(socket.af_inet, socket.sock_stream) 22 sock.connect((sys.argv[1], 8888)) # 23 sock.send(os.getlogin() + '\n') # 24 message = sock.recv(4096) # 25 print message # 26 sock.close() # hello-client.py hello-client.py Sockets API socket(2) bind(2) listen(2) accept(2) connect(2) recv(2) send(2) close(2) gethostbyname(3) L22
51 $./hello-client.py localhost Hello schen My time is Sun May 13 12:56: $./hello-client.py atom Hello schen Java Python Sockets Sockets API tar muduo beta.tar.gz muduo Linux timerfd eventfd Linux Debian 6.0 Squeeze / Ubuntu LTS g bit 64-bit x86 muduo Fedora 13 CentOS 6 Arch Linux AUR 4 Linux muduo backport.diff muduo Samsung S3C2440 ARM9 Raspberry Pi ARM11 muduo armlinux.diff muduo CMake 6 build system $ sudo apt-get install cmake muduo Boost 7 $ sudo apt-get install libboost-dev libboost-test-dev Debian 5.0 Lenny Ubuntu 8.04 CentOS CentOS Protobuf 7 TR1 Boost
52 128 6 muduo muduo curl c-ares DNS Google Protobuf cmake $ sudo apt-get install libcurl4-openssl-dev libc-ares-dev $ sudo apt-get install protobuf-compiler libprotobuf-dev muduo $ tar zxf muduo beta.tar.gz $ cd muduo/ $./build.sh -j2 muduo../build/debug/{bin,lib} $./build.sh install muduo../build/debug-install/{include,lib} muduo-protorpc muduo-udns release -O2 $ BUILD_TYPE=release./build.sh -j2 muduo../build/release/{bin,lib} $ BUILD_TYPE=release./build.sh install muduo../build/release-install/{include,lib} muduo-protorpc muduo-udns muduo 1.0 BUILD_TYPE release bin/inspector_test Linux box IP muduo muduo 8 C++ muduo../build/debug-install/include../build/debug-install/lib -lmuduo_net -lmuduo_base CMake makefile muduo muduo-tutorial 8 11
53 muduo muduo -- build.sh -- ChangeLog -- CMakeLists.txt -- License -- README -- muduo muduo -- base ::muduo namespace \-- net ::muduo::net namespace -- poller poll(2) epoll(4) IO multiplexing -- http Web -- inspect Web \-- protorpc Google Protobuf RPC -- examples \-- TODO muduo class ThreadPool class muduo/ base/threadpool.h muduo/base/threadpool.cc muduo/base muduo \-- base -- AsyncLogging.{h,cc} backend -- Atomic.h -- BlockingQueue.h -- BoundedBlockingQueue.h -- Condition.h Mutex.h -- copyable.h tag -- CountDownLatch.{h,cc} -- Date.{h,cc} Julian -- Exception.{h,cc} stack trace -- Logging.{h,cc} AsyncLogging -- Mutex.h -- ProcessInfo.{h,cc} -- Singleton.h singleton -- StringPiece.h Google -- tests -- Thread.{h,cc} -- ThreadLocal.h -- ThreadLocalSingleton.h singleton -- ThreadPool.{h,cc} -- Timestamp.{h,cc} UTC -- TimeZone.{h,cc} \-- Types.h muduo::string
54 130 6 muduo muduo Reactor EventLoop IO muduo object-based objectoriented boost::function + boost::bind muduo class muduo/net muduo/net/poller 4300 muduo \-- net -- Acceptor.{h,cc} -- Buffer.{h,cc} IO -- Callbacks.h -- Channel.{h,cc} Socket -- CMakeLists.txt -- Connector.{h,cc} -- Endian.h -- EventLoop.{h,cc} -- EventLoopThread.{h,cc} EventLoop -- EventLoopThreadPool.{h,cc} muduo IO -- InetAddress.{h,cc} IP -- Poller.{h,cc} IO multiplexing -- poller IO multiplexing -- DefaultPoller.cc MUDUO_USE_POLL -- EPollPoller.{h,cc} epoll(4) IO multiplexing \-- PollPoller.{h,cc} poll(2) IO multiplexing -- Socket.{h,cc} Sockets -- SocketsOps.{h,cc} Sockets API -- TcpClient.{h,cc} TCP -- TcpConnection.{h,cc} muduo TcpServer.{h,cc} TCP -- tests -- Timer.{h,cc} -- TimerId.h \-- TimerQueue.{h,cc} -lmuduo_http -lmuduo_inspect HttpServer Inspector http Java JMX 9.5 muduo/net/{http,inspect,protorpc}
55 muduo \-- net -- http HTTP HTTP -- CMakeLists.txt -- HttpContext.h -- HttpRequest.h -- HttpResponse.{h,cc} -- HttpServer.{h,cc} \-- tests/httpserver_test.cc HTTP -- inspect HTTP -- CMakeLists.txt -- Inspector.{h,cc} -- ProcessInspector.{h,cc} \-- tests/inspector_test.cc \-- protorpc Google Protobuf RPC -- CMakeLists.txt -- google-inl.h -- RpcChannel.{h,cc} -- RpcCodec.{h,cc} -- rpc.proto \-- RpcServer.{h,cc} muduo muduo 5 Buffer EventLoop TcpConnection TcpClient TcpServer -- include \-- muduo -- base \-- net -- Buffer.h -- Callbacks.h -- Channel.h -- Endian.h -- EventLoop.h -- EventLoopThread.h -- InetAddress.h -- TcpClient.h -- TcpConnection.h -- TcpServer.h -- TimerId.h -- http -- HttpRequest.h -- HttpResponse.h \-- HttpServer.h -- inspect -- Inspector.h \-- ProcessInspector.h
56 132 6 muduo \-- protorpc -- RpcChannel.h -- RpcCodec.h \-- RpcServer.h \-- lib -- libmuduo_base.a, libmuduo_net.a -- libmuduo_http.a, libmuduo_inspect.a \-- libmuduo_protorpc.a 6-1 muduo poller/epollpoller.h SocketsOps.h poller/pollpoller.h Poller.h Acceptor.h Socket.h EventLoopThreadPool.h EventLoopThread.h TcpClient.h TcpServer.h 6-1 TimerQueue.h Timer.h EventLoop.h TcpConnection.h Connector.h Channel.h Callbacks.h TimerId.h Buffer.h InetAddress.h muduo forward declaration Acceptor.h Channel.h Connector.h TcpConnection.h EventLoop class EventLoop.h TcpClient.h Connector class TcpServer.h Acceptor EventLoopThreadPool EventLoop.h Poller TimerQueue TcpConnection.h Channel Socket class Buffer Netty ChannelBuffer buffer class buffer read(2)/write(2) 7.4
57 InetAddress IPv4 end point IP gethostbyname(3) IO EventLoop Reactor EventLoop IO eventfd(2) pipe(2) TimerQueue Poller IO multiplexing EventLoopThread EventLoop::loop() TcpConnection TCP TcpClient TcpServer TcpConnection shared_ptr Buffer TcpConnection Buffer InetAddress class Channel selectable IO channel IO file descriptor Acceptor Connector EventLoop TimerQueue TcpConnection Socket RAII handle file descriptor fd Acceptor TcpConnection EventLoop TimerQueue fd Socket class SocketsOps Sockets Poller PollPoller EPollPoller EventLoop PollPoller EPollPoller poll(2) epoll(4) IO multiplexing poll poll(2) strace(1) Connector TCP TcpClient Acceptor TCP TcpServer TimerQueue timerfd poll/epoll_wait TimerQueue std::map Timer O(log N) N EventLoop EventLoopThreadPool IO TcpConnection EventLoop TcpServer
58 134 6 muduo 6-2 muduo Buffer TcpConnection EventLoop Channel +loop() +runafter() +runevery() +runat() +runinloop() +queueinloop() File Descriptor Socket owns -fd_ : File Desc. +handleevent() TcpConnection Acceptor Connector +poll() Poller -handleread() -handlewrite() -handleclose() -handleerror() -handleread() -handlewrite() -handleerror() TcpServer TcpClient PollPoller EPollPoller +poll() +poll() muduo examples Boost.Asio Java Netty Python Twisted examples -- asio Boost.Asio -- chat codec \-- tutorial timers -- cdns c-ares DNS -- curl curl HTTP -- filetransfer TCP -- hub pub/sub/hub -- idleconnection -- maxconnection -- multiplexer 1:n -- netty JBoss Netty -- discard -- echo \-- uptime TCP -- pingpong pingpong
59 protobuf Google Protobuf -- codec -- rpc RPC Sudoku \-- rpcbench RPC -- roundtrip -- shorturl -- simple 5 -- allinone 5 -- chargen RFC chargenclient chargen -- daytime RFC discard RFC echo RFC time RFC 868 \-- timeclient time -- socks4a Socks4a TcpClient -- sudoku muduo -- twisted Python Twisted \-- finger finger01 ~ 07 \-- zeromq ZeroMQ muduo License muduo UDNS DNS RPC muduo one loop per thread + thread pool EventLoop TcpConnection EventLoop IO file descriptor TcpConnection EventLoop TCP TCP TcpConnection EventLoop TcpServer accept(2) TcpConnection IO accept(2) EventLoop EventLoop- ThreadPool round-robin 6.6 Sudoku muduo 9 muduo-protorpc Ubuntu Linux apt-get Protobuf Protobuf 2.4.1
60 136 6 muduo muduo TCP muduo bug signal muduo 8 muduo Linux 2.6.x TCP IO IO muduo TCP Sockets API Brooks 11 muduo accidental complexity TCP recv(2) accept(2) send(2) Win32 TCP 1. accept connect TCP 2. close shutdown read(2) 0 10 Signal signalfd(2) EventLoop muduo-protorpc zurg slave 11
61 TCP close(2) back-off edge trigger level trigger 12 EPOLLOUT busy-loop epoll(4) poll(2) 40kB TCP 25kB 15kB OS 15kB TCP socket 50kB kb 50kB write() lighttpd \r\n\r\n bug 13 10ms readable lighttpd
62 138 6 muduo kB (s) 1GB muduo readv(2) IO muduo echo muduo echo 1. EchoServer class examples/simple/echo/echo.h 4 #include <muduo/net/tcpserver.h> 5 6 // RFC class EchoServer 8 { 9 public: 10 EchoServer(muduo::net::EventLoop* loop, 11 const muduo::net::inetaddress& listenaddr); void start(); // calls server_.start(); private: 16 void onconnection(const muduo::net::tcpconnectionptr& conn); void onmessage(const muduo::net::tcpconnectionptr& conn, 19 muduo::net::buffer* buf, 20 muduo::timestamp time); muduo::net::eventloop* loop_; 23 muduo::net::tcpserver server_; 24 }; examples/simple/echo/echo.h
63 examples/simple/echo/echo.cc 10 EchoServer::EchoServer(muduo::net::EventLoop* loop, 11 const muduo::net::inetaddress& listenaddr) 12 : loop_(loop), 13 server_(loop, listenaddr, "EchoServer") 14 { 15 server_.setconnectioncallback( 16 boost::bind(&echoserver::onconnection, this, _1)); 17 server_.setmessagecallback( 18 boost::bind(&echoserver::onmessage, this, _1, _2, _3)); 19 } examples/simple/echo/echo.cc 2. EchoServer::onConnection() EchoServer::onMessage() examples/simple/echo/echo.cc 26 void EchoServer::onConnection(const muduo::net::tcpconnectionptr& conn) 27 { 28 LOG_INFO << "EchoServer - " << conn->peeraddress().toipport() << " -> " 29 << conn->localaddress().toipport() << " is " 30 << (conn->connected()? "UP" : "DOWN"); 31 } void EchoServer::onMessage(const muduo::net::tcpconnectionptr& conn, 34 muduo::net::buffer* buf, 35 muduo::timestamp time) 36 { 37 muduo::string msg(buf->retrieveallasstring()); 38 LOG_INFO << conn->name() << " echo " << msg.size() << " bytes, " 39 << "data received at " << time.tostring(); 40 conn->send(msg); 41 } examples/simple/echo/echo.cc L37 L40 echo L40 send(msg) muduo event handler onconnection() conn TcpConnection shared_ptr TcpConnection::connected() bool TcpConnection peeraddress() localaddress() InetAddress IP port
64 140 6 muduo onmessage() conn TCP buf buf retrieve buf buffer time epoll_wait(2) read(2) Timestamp pass-by-value pass-by-(const)reference x main() EventLoop 1 #include "echo.h" 2 3 #include <muduo/base/logging.h> 4 #include <muduo/net/eventloop.h> 5 6 // using namespace muduo; 7 // using namespace muduo::net; 8 9 int main() 10 { 11 LOG_INFO << "pid = " << getpid(); 12 muduo::net::eventloop loop; 13 muduo::net::inetaddress listenaddr(2007); 14 EchoServer server(&loop, listenaddr); 15 server.start(); 16 loop.loop(); 17 } examples/simple/echo/main.cc examples/simple/echo/main.cc muduo/examples/simple/echo echo TcpServer EventLoop TcpConnection Buffer class class class namespace finger Python Twisted Reactor muduo muduo deferreds finger Twisted muduo finger finger01 finger07 examples/twisted/ finger
65 #include <muduo/net/eventloop.h> 2 3 using namespace muduo; 4 using namespace muduo::net; 5 6 int main() 7 { 8 EventLoop loop; 9 loop.loop(); 10 } examples/twisted/finger/finger01.cc examples/twisted/finger/finger01.cc muduo examples/twisted/finger/finger02.cc 1 #include <muduo/net/eventloop.h> 2 #include <muduo/net/tcpserver.h> 3 4 using namespace muduo; 5 using namespace muduo::net; 6 7 int main() 8 { 9 EventLoop loop; 10 TcpServer server(&loop, InetAddress(1079), "Finger"); 11 server.start(); 12 loop.loop(); 13 } examples/twisted/finger/finger02.cc 3. namespace 7 void onconnection(const TcpConnectionPtr& conn) 8 { 9 if (conn->connected()) 10 { 11 conn->shutdown(); 12 } 13 } int main() 16 { 17 EventLoop loop; 18 TcpServer server(&loop, InetAddress(1079), "Finger"); 19 server.setconnectioncallback(onconnection); examples/twisted/finger/finger03.cc
66 142 6 muduo 20 server.start(); 21 loop.loop(); 22 } examples/twisted/finger/finger03.cc 4. \r\n Buffer::findCRLF() O(N 2 ) CPU examples/twisted/finger/finger04.cc 7 void onmessage(const TcpConnectionPtr& conn, 8 Buffer* buf, 9 Timestamp receivetime) 10 { 11 if (buf->findcrlf()) 12 { 13 conn->shutdown(); 14 } 15 } int main() 18 { 19 EventLoop loop; 20 TcpServer server(&loop, InetAddress(1079), "Finger"); 21 server.setmessagecallback(onmessage); 22 server.start(); 23 loop.loop(); 24 } examples/twisted/finger/finger04.cc 5. \r\n --- examples/twisted/finger/finger04.cc :03: examples/twisted/finger/finger05.cc :06:05 -7,12 void onmessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp receivetime) { if (buf->findcrlf()) { + conn->send("no such user\r\n"); conn->shutdown(); } }
67 UserMap L30 UserMap examples/twisted/finger/finger06.cc 9 typedef std::map<string, string> UserMap; 10 UserMap users; string getuser(const string& user) 13 { 14 string result = "No such user"; 15 UserMap::iterator it = users.find(user); 16 if (it!= users.end()) 17 { 18 result = it->second; 19 } 20 return result; 21 } void onmessage(const TcpConnectionPtr& conn, 24 Buffer* buf, 25 Timestamp receivetime) 26 { 27 const char* crlf = buf->findcrlf(); 28 if (crlf) 29 { 30 string user(buf->peek(), crlf); 31 conn->send(getuser(user) + "\r\n"); 32 buf->retrieveuntil(crlf + 2); 33 conn->shutdown(); 34 } 35 } int main() 38 { 39 EventLoop loop; 40 TcpServer server(&loop, InetAddress(1079), "Finger"); 41 server.setmessagecallback(onmessage); 42 server.start(); 43 loop.loop(); 44 } examples/twisted/finger/finger06.cc 7. UserMap L examples/twisted/finger/finger06.cc :14: examples/twisted/finger/finger07.cc :15:22 -36,6 int main() { + users["schen"] = "Happy and well"; EventLoop loop; TcpServer server(&loop, InetAddress(1079), "Finger");
68 144 6 muduo server.setmessagecallback(onmessage); server.start(); loop.loop(); } telnet(1) finger Telnet $./bin/twisted_finger07 $ telnet localhost 1079 Trying ::1... Trying Connected to localhost. Escape character is '^]'. muduo No such user Connection closed by foreign host. $ telnet localhost 1079 Trying ::1... Trying Connected to localhost. Escape character is '^]'. schen Happy and well Connection closed by foreign host. 6.5 muduo muduo TCP
69 muduo percentile muduo Boost.Asio libevent2 muduo ping pong muduo Boost.Asio 15% libevent2 18% 70%. boost 1.40 asio asio libevent rc muduo asio libevent2 ping pong recipes/pingpong/libevent/ muduo libevent2 muduo examples/pingpong/ gist 17 muduo asio -O2 -finline-limit=1000 $ BUILD_TYPE=release./build.sh # muduo DELL 490 Intel Xeon E5320 CPU GHz 16GiB Ubuntu Linux Server LTS x86_64 g
70 146 6 muduo asio 18 ping pong muduo asio libevent2 ping pong echo TCP echo echo ZeroMQ 1/10/100/1000/ /2/3/4 8 4 ping pong 16KiB shell CPU TCP 110MiB/s Python CPU CPU 1 CPU
71 吞吐量 (MiB/s) 单线程 连接数 muduo asio asio libevent muduo libevent2 70% libevent2 socket 4096 buffer.c evbuffer_ read() muduo muduo
72 第6章 148 muduo 网络库简介 测试结果表明 muduo 的吞吐量平均比 libevent2 高 18% 以上 多线程测试的结果 见图 6-5 数字越大越好 多线程 (100 连接) 多线程 (1000 连接) 吞吐量 (MiB/s) 吞吐量 (MiB/s) 线程数 muduo muduo asio asio asio asio 线程数 0 图 6-5 测试结果表明 muduo 的吞吐量平均比 asio 高 15% 以上 讨论 muduo 出乎意料地比 asio 性能优越 我想主要得益于其简单的设计和简洁的 代码 asio 在多线程测试中表现不佳 我猜测其主要原因是测试代码只使用了一 个 io_service 如果改用 io_service per CPU 的话 其性能应该有所提高 我 对 asio 的了解程度仅限于能读懂其代码 希望能有 asio 高手编写 io_service per CPU 的 ping pong 测试 以便与 muduo 做一个公平的比较 由于 libevent2 每次最多从网络读取 4096 字节 这大大限制了它的吞吐量 ping pong 测试很容易实现 欢迎其他网络库 ACE POCO libevent 等 也能 加入到对比中来 期待这些库的高手出马 击鼓传花 对比 muduo 与 libevent2 的事件处理效率 前 面 我 们 比 较 了 muduo 和 libevent2 的 吞 吐 量 得 到 的 结 论 是 muduo 比 libevent2 快 18%. 有人会说 libevent2 并不是为高吞吐量的应用场景而设计的 这样的比较不公平 胜之不武 为了公平起见 这回我们用 libevent2 自带的性能测 试程序 击鼓传花 来对比 muduo 和 libevent2 在高并发情况下的 IO 事件处理效率 Linux 多线程服务端编程 使用 muduo C++ 网络库 (excerpt)
73 DELL E socketpair(2) pipe(2) ~ libevent2 test/bench.c rc bug libevent2 muduo examples/pingpong/bench.cc event watcher libev 19 timer event IO event libev Marc Lehmann muduo libevent libevent2 + muduo recipes/pingpong/libevent/run_bench.sh
74 150 6 muduo muduo libevent2 muduo (ctl_add) total time per iteration 100 active clients Dell WS file descriptors muduo libevent2 muduo (ctl_add) 1000 active clients file descriptors 700 time spent in event processing 100 active clients file descriptors muduo libevent2 muduo (ctl_add) muduo libevent2 muduo (ctl_add) 1000 active clients file descriptors time (in us) (lower is better) time (in us) (lower is better) time (in us) (lower is better) time (in us) (lower is better) 6-6
75 libevent2 event watcher muduo 20% 2. a libevent2 b libevent2 muduo muduo 1. muduo 2. libevent2 libev Marc Lehmann 21 libevent2 muduo epoll_ctl(fd, EPOLL_CTL_ ADD,...) event watcher 24 muduo epoll_ctl(fd, EPOLL_CTL_MOD,...) event watcher libevent2 epoll_ctl(fd, EPOLL_CTL_ADD,...) fd EEXIST File exists EPOLL_CTL_ADD EPOLL_CTL_MOD libevent2 muduo EPOLL_CTL_ADD event watcher 6-6 muduo libevent2 kernel muduo muduo/net/poller/epollpoller.cc CPU 2.4 GHz 1.86 GHz 21
76 152 6 muduo muduo libevent2 muduo (ctl_add) total time per iteration 100 active clients Dell E file descriptors muduo libevent2 muduo (ctl_add) 1000 active clients file descriptors 400 time spent in event processing 100 active clients file descriptors muduo libevent2 muduo (ctl_add) muduo libevent2 muduo (ctl_add) 1000 active clients file descriptors time (in us) (lower is better) time (in us) (lower is better) time (in us) (lower is better) time (in us) (lower is better) 6-7
77 muduo libevent muduo muduo Nginx Nginx muduo HTTP muduo HTTP muduo/net/http/ HTTP server 8 DELL 490 Xeon E5320 CPU ab 22 weighttp 23 4 i CPU Nginx muduo HTTP server HTTP client muduo HTTP muduo/net/http/tests/httpserver_test.cc void onrequest(const HttpRequest& req, HttpResponse* resp) { if (req.path() == "/") { //... } else if (req.path() == "/hello") { resp->setstatuscode(httpresponse::k200ok); resp->setstatusmessage("ok"); resp->setcontenttype("text/plain"); resp->addheader("server", "Muduo"); resp->setbody("hello, world!\n"); } else { resp->setstatuscode(httpresponse::k404notfound); resp->setstatusmessage("not Found"); resp->setcloseconnection(true); } } int main(int argc, char* argv[]) { int numthreads = 0;
78 154 6 muduo if (argc > 1) { benchmark = true; Logger::setLogLevel(Logger::WARN); numthreads = atoi(argv[1]); } EventLoop loop; HttpServer server(&loop, InetAddress(8000), "dummy"); server.sethttpcallback(onrequest); server.setthreadnum(numthreads); server.start(); loop.loop(); } muduo/net/http/tests/httpserver_test.cc Nginx HTTP echo 24 #user nobody; worker_processes 4; events { worker_connections 10240; } http { include default_type mime.types; application/octet-stream; access_log sendfile tcp_nopush off; on; on; keepalive_timeout 65; server { listen 8080; server_name localhost; location / { root html; index index.html index.htm; } } } location /hello { default_type text/plain; echo "hello, world!"; }
79 Requests per second Requests per second /hello "hello, world!"./ab -n k -r -c :8080/hello 6-8 HTTP ab CPU 70% muduo vs. Nginx 1 worker/thread muduo Nginx muduo 4 Nginx top(1) ab CPU 85% weighttp muduo vs. Nginx 4 workers/threads muduo Nginx
80 Average latency [us] lower is better muduo CPU top(1) workers/threads muduo 4 83% Nginx 4 75% workers/threads muduo 4 85% Nginx 4 78% Nginx CPU CPU CPU benchmark IO benchmark CPU 100% IO muduo Nginx muduo Nginx muduo qps 10 muduo HTTP HTTP muduo Nginx httpd muduo muduo ZeroMQ ZeroMQ 25 muduo muduo examples/zeromq/ ping pong echo KiB muduo ZeroMQ muduo vs. ZeroMQ latency on GbE k 2k 4k 8k 16k muduo ZeroMQ
81 6.6 muduo muduo Sudoku Solver muduo muduo examples/sudoku/ Sudoku Solver Sudoku Solver 9.8 muduo Buffer echo A echo TCP echo Sudoku \r\n TCP [id:]<81digits>\r\n [id:]<81digits>\r\n [id:]nosolution\r\n [id:] id Parallel Pipelining id Parallel Pipelining Protobuf RPC out-of-order RPC
82 158 6 muduo <81digits> Sudoku Sudoku NoSolution \r\n \r\n 2 a: \r\n a: \r\n 3 b: \r\n b:nosolution\r\n telnet Sudoku Solver Sudoku Client Sudoku Solver = 81 Sudoku Sudoku 28 Sudoku string solvesudoku(const string& puzzle); <81digits> <81digits> NoSolution pure function echo EchoServer SudokuServer onmessage() examples/sudoku/server_basic.cc onmessage() solvesudoku() TCP 28
83 6.6 muduo 159 const int kcells = 81; // 81 examples/sudoku/server_basic.cc void onmessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp) { LOG_DEBUG << conn->name(); size_t len = buf->readablebytes(); while (len >= kcells + 2) // 2 { const char* crlf = buf->findcrlf(); if (crlf) // { string request(buf->peek(), crlf); // string id; buf->retrieveuntil(crlf + 2); // retrieve string::iterator colon = find(request.begin(), request.end(), ':'); if (colon!= request.end()) // id { id.assign(request.begin(), colon); request.erase(request.begin(), colon+1); } if (request.size() == implicit_cast<size_t>(kcells)) // { string result = solvesudoku(request); // if (id.empty()) { conn->send(result+"\r\n"); } else { conn->send(id+":"+result+"\r\n"); } } else // { conn->send("bad Request!\r\n"); conn->shutdown(); } } else // { break; } } } examples/sudoku/server_basic.cc server_basic.cc Sudoku 7.4 CPU server_basic CPU
84 160 6 muduo server_basic 8 8 server_basic (s) 8 server_basic load balancer W. Richard Stevens UNIX 2 27 Client-Server Design Alternatives [UNP] 3 30 UNP CSDA [UNP] non-blocking IO Sockets API 2000 HTTP httpd Reactor IBM Lotus TCP Lotus Linux IBM Linux Lotus Server Linux POSA chat chat A TCP echo/httpd/sudoku chat httpd/sudoku
85 6.6 muduo 方案 并发模型 [UNP] 对应 多进程 多线程 阻塞 IO IO 复用 长连接 0 accept+read/write 0 否 否 是 否 否 无 否 低 否 是 常 一次服务一个客户 1 accept+fork 1 是 否 是 否 是 低 是 高 否 是 变 process-per-connection 2 accept+thread 6 否 是 是 否 是 中 是 中 是 是 变 thread-per-connection 3 prefork 2/3/4/5 是 否 是 否 是 低 是 高 否 是 变 见 [UNP] 4 pre threaded 7/8 否 是 是 否 是 中 是 中 是 是 变 见 [UNP] 5 poll (reactor) 6.8 节 否 否 否 是 是 高 否 低 是 是 常 单线程 reactor 6 reactor + thread-per-task 无 否 是 否 是 是 中 是 中 是 否 变 thread-per-request 7 reactor + worker thread 无 否 是 否 是 是 中 是 中 是 是 变 worker-thread-per-connection 8 reactor + thread pool 无 否 是 否 是 是 高 是 低 是 否 常 主线程 IO, 工作线程计算 9 reactors in threads 无 否 是 否 是 是 高 是 低 是 是 常 one loop per thread (muduo) 10 reactors in processes 无 是 否 否 是 是 高 是 低 否 是 常 one loop per process (Nginx) 11 reactors + thread pool 无 否 是 否 是 是 高 是 低 是 否 常 最灵活的 IO 与 CPU 配置 并发性 多核 开销 互通 顺序性 线程数 特点
86 162 6 muduo UNP CSDA Reactor muduo micro benchmark Thread_ bench.cc BlockingQueue_bench.cc E5320 Linux fork()+exit(): 534.7µs pthread_create()+pthread_join(): 42.5µs 26.1µs push/pop a blocking queue : 11.5µs Sudoku resolve: 100us µs 0 iterative [UNP] Figure 1.9 [UNP] daytime write-only Python 0 echo server Python recipes/python/echo-iterative.py 3 import socket 4 5 def handle(client_socket, client_address): 6 while True: 7 data = client_socket.recv(4096) 8 if data: 9 sent = client_socket.send(data) # sendall? 10 else: 11 print "disconnect", client_address 12 client_socket.close() 13 break if name == " main ": 16 listen_address = (" ", 2007) 17 server_socket = socket.socket(socket.af_inet, socket.sock_stream) 18 server_socket.bind(listen_address) 19 server_socket.listen(5) while True: 22 (client_socket, client_address) = server_socket.accept() 23 print "got connection from", client_address 24 handle(client_socket, client_address) recipes/python/echo-iterative.py L6~L13 echo L21~L24
87 6.6 muduo 163 L9 sendall() 1 Unix [UNP] child-per-client fork()-per-client process-per-connection PostgreSQL Perforce fork() fork() Sudoku Python L9~L16 self.request client_socket ForkingTCPServer EchoHandler.handle() IO recipes/python/echo-fork.py 1 #!/usr/bin/python 2 3 from SocketServer import BaseRequestHandler, TCPServer 4 from SocketServer import ForkingTCPServer, ThreadingTCPServer 5 6 class EchoHandler(BaseRequestHandler): 7 def handle(self): 8 print "got connection from", self.client_address 9 while True: 10 data = self.request.recv(4096) 11 if data: 12 sent = self.request.send(data) # sendall? 13 else: 14 print "disconnect", self.client_address 15 self.request.close() 16 break if name == " main ": 19 listen_address = (" ", 2007) 20 server = ForkingTCPServer(listen_address, EchoHandler) 21 server.serve_forever() recipes/python/echo-fork.py 2 Java thread-per-connection Java 1.4 NIO Java 1 Sudoku scheduler Python ThreadingTCPServer EchoHandler.handle()
88 164 6 muduo $ diff -U2 echo-fork.py echo-thread.py if name == " main ": listen_address = (" ", 2007) - server = ForkingTCPServer(listen_address, EchoHandler) + server = ThreadingTCPServer(listen_address, EchoHandler) server.serve_forever() EchoHandler.handle() 0 $ diff -U2 echo-fork.py echo-single.py if name == " main ": listen_address = (" ", 2007) - server = ForkingTCPServer(listen_address, EchoHandler) + server = TCPServer(listen_address, EchoHandler) server.serve_forever() 3 1 [UNP] accept(2) thundering herd 4 2 [UNP] 3 4 Apache httpd thread of control read() TCP read() write() / read() TCP echo client stdin proxy a b b a proxy A TCP / [UNP] echo client 7.13 Python TCP relay Python Pinhole IO multiplexing select/poll/epoll/kqueue thread of control IO IO select/poll non-blocking IO non-blocking IO buffer 7.4 IO multiplexing event-driven Doug Schmidt
89 6.6 muduo 165 Reactor event-driven Reactor / libevent muduo Netty twisted POE proxy Python IO multiplexing echo server 29 non-blocking L28 socket L14 L15~L32 IO fileno L16, L17 listening fd accept IO watch list connections L18~L23 L24~L32 echo L28 recipes/python/echo-poll.py 6 server_socket = socket.socket(socket.af_inet, socket.sock_stream) 7 server_socket.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1) 8 server_socket.bind(('', 2007)) 9 server_socket.listen(5) 10 # server_socket.setblocking(0) 11 poll = select.poll() # epoll() should work the same 12 poll.register(server_socket.fileno(), select.pollin) connections = {} 15 while True: 16 events = poll.poll(10000) # 10 seconds 17 for fileno, event in events: 18 if fileno == server_socket.fileno(): 19 (client_socket, client_address) = server_socket.accept() 20 print "got connection from", client_address 21 # client_socket.setblocking(0) 22 poll.register(client_socket.fileno(), select.pollin) 23 connections[client_socket.fileno()] = client_socket 24 elif event & select.pollin: 25 client_socket = connections[fileno] 26 data = client_socket.recv(4096) 27 if data: 28 client_socket.send(data) # sendall() partial? 29 else: 30 poll.unregister(fileno) 31 client_socket.close() 32 del connections[fileno] recipes/python/echo-poll.py IO multiplexing 29
90 166 6 muduo listen TCP 3 L28~L30 $ diff echo-poll.py chat-poll.py -U4 --- echo-poll.py :50: chat-poll.py :50: elif event & select.pollin: 24 clientsocket = connections[fileno] 25 data = clientsocket.recv(4096) 26 if data: 27 - clientsocket.send(data) # sendall() partial? 28 + for (fd, othersocket) in connections.iteritems(): 29 + if othersocket!= clientsocket: 30 + othersocket.send(data) # sendall() partial? 31 else: 32 poll.unregister(fileno) 33 clientsocket.close() 34 del connections[fileno] Doug Schmidt routine Reactor Windows GUI IO multiplexing WndProc switch-case GUI 1 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) 2 { 3 switch (message) 4 { 5 case WM_DESTROY: 6 PostQuitMessage(0); 7 return 0; 8 // many more cases 9 } 10 return DefWindowProc (hwnd, message, wparam, lparam) ; 11 } Reactor IO
91 6.6 muduo 167 Reactor 6-11 select/poll/epoll_wait IO Reactor IO socket poll poll 6-11 compute() 100ms sleep() IO IO Thread IO Thread Conn 1 readable poll Conn 1 readable poll read decode Conn 2 readable read 1 decode compute compute encode encode Conn 2 readable write poll read decode compute encode write poll write 1 poll read 2 decode compute encode write 2 poll Reactor 6-11 server_basic.cc IO CPU read(2) 5 poll(2) read(2)
92 168 6 muduo Python Reactor L42~L46 handlers listening fd handle_accept handler handle_request handle_input handle_input recipes/python/echo-reactor.py 6 server_socket = socket.socket(socket.af_inet, socket.sock_stream) 7 server_socket.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1) 8 server_socket.bind(('', 2007)) 9 server_socket.listen(5) 10 # serversocket.setblocking(0) poll = select.poll() # epoll() should work the same 13 connections = {} 14 handlers = {} def handle_input(socket, data): 17 socket.send(data) # sendall() partial? def handle_request(fileno, event): 20 if event & select.pollin: 21 client_socket = connections[fileno] 22 data = client_socket.recv(4096) 23 if data: 24 handle_input(client_socket, data) 25 else: 26 poll.unregister(fileno) 27 client_socket.close() 28 del connections[fileno] 29 del handlers[fileno] def handle_accept(fileno, event): 32 (client_socket, client_address) = server_socket.accept() 33 print "got connection from", client_address 34 # client_socket.setblocking(0) 35 poll.register(client_socket.fileno(), select.pollin) 36 connections[client_socket.fileno()] = client_socket 37 handlers[client_socket.fileno()] = handle_request poll.register(server_socket.fileno(), select.pollin) 40 handlers[server_socket.fileno()] = handle_accept while True: 43 events = poll.poll(10000) # 10 seconds 44 for fileno, event in events: 45 handler = handlers[fileno] 46 handler(fileno, event) recipes/python/echo-reactor.py
93 6.6 muduo 169 handle_input $ diff echo-reactor.py chat-reactor.py -U1 def handle_input(socket, data): - socket.send(data) # sendall() partial? + for (fd, other_socket) in connections.iteritems(): + if other_socket!= socket: + other_socket.send(data) # sendall() partial? IO IO IO Windows GUI 6 Sudoku Reactor CPU 8 out-of-order 2 Sudoku 1 id response request 7 IO thread-per-connection client CPU 6 TCP burst requests 8 core % CPU IO Reactor thread pool IO Sudoku Solver examples/sudoku/server_threadpool.cc
94 170 6 muduo IO Thread Threads in pool Conn 1 readable poll wait wait Conn 2 readable read poll read put in pool put in pool decode poll write 2 write 1 poll compute encode wait decode compute encode wait Reactor 5 onmessage() ThreadPool 8 id $ diff server_basic.cc server_threadpool.cc -u --- server_basic.cc :19: server_threadpool.cc :15: ,16 void onmessage(const TcpConnectionPtr& conn,... if (puzzle.size() == implicit_cast<size_t>(kcells)) { - string result = solvesudoku(puzzle); - if (id.empty()) - { - conn->send(result+"\r\n"); - } - else - { - conn->send(id+":"+result+"\r\n"); - } + threadpool_.run(boost::bind(&solve, conn, puzzle, id)); -114,17 + static void solve(const TcpConnectionPtr& conn, + const string& puzzle, + const string& id) + {
95 6.6 muduo string result = solvesudoku(puzzle); + if (id.empty()) + { + conn->send(result+"\r\n"); + } + else + { + conn->send(id+":"+result+"\r\n"); + } + } + EventLoop* loop_; TcpServer server_; + ThreadPool threadpool_; Timestamp starttime_; }; IO Java Servlet 2.x IO fsync(2)/fdatasync(2) 30 IO Reactor 9 Reactor 9 muduo Netty one loop per thread main Reactor accept(2) sub Reactor muduo round-robin sub Reactor sub Reactor CPU muduo Reactor pool CPU 8 11 IO Reactor 8 9 thread pool Reactor IO IO muduo Linux IO
96 172 6 muduo Base IO Thread IO Thread 1 IO Thread 2 Conn 1 established poll poll poll Conn 2 established accept poll assign poll accept assign Conn 3 established poll accept assign poll Conn 1 readable Conn 2 readable poll poll read decode compute read encode decode write poll examples/sudoku/server_multiloop.cc server_basic.cc server_.setthreadnum(numthreads); $ diff server_basic.cc server_multiloop.cc -up --- server_basic.cc :40: server_multiloop.cc :39: ,19 class SudokuServer - SudokuServer(EventLoop* loop, const InetAddress& listenaddr) + SudokuServer(EventLoop* loop, const InetAddress& listenaddr, int numthreads) : loop_(loop), server_(loop, listenaddr, "SudokuServer"), starttime_(timestamp::now()) { server_.setconnectioncallback( boost::bind(&sudokuserver::onconnection, this, _1)); server_.setmessagecallback( boost::bind(&sudokuserver::onmessage, this, _1, _2, _3)); + server_.setthreadnum(numthreads); } 10 Nginx Reactor IO IO IO
97 6.6 muduo Base IO Thread IO Thread 1 IO Thread 2 Threads in pool Conn 1 established poll poll poll wait wait Conn 2 established accept poll assign poll accept assign poll Conn 2 readable poll Conn 1 readable read read decode decode put in pool compute poll put in pool poll encode compute write wait encode write poll wait server_.setthreadnum(numthreads); event loop event loops ZeroMQ 31 event loop event loop muduo::tcpserver::setthreadnum() event loop IO event loop IO thread pool event loop TCP TCP event loop event loop muduo event loop
98 174 6 muduo 10 event loop 1ms event loop event handler epoll_wait() event loop event loop 3.3 C++ one loop per thread + thread pool event loop non-blocking IO thread pool : Reactor in-house C++ muduo 32 5 muduo IO 2 thread-per-connection 1 N 5 Reactor 1 8 Reactor + 1 C 2 9 one loop per thread 1 C 1 11 one loop per thread + 1 C 1 C N C 1 C 2 CPU 32 Characteristics of multithreading models for high-performance IO driven network applications
99 6.6 muduo 175 IO TCP read()/write() 5 IO concurrent parallel 8 Reactor VIP VIP 5 VIP 6-11 muduo IO 11 IO
100 3
101 11.5 boost::function boost::bind 447 pimpl explicit forward pimpl pimpl C++ C libevent2 struct event_base opaque pointer libevent non-virtual virtual virtual function bind-byvtable-offset non-virtual function bind-by-name loader resolution mangled name Internet IP C Java JNI C Python/Perl/Ruby C C C Linux class free function muduo/base/ Timestamp.h class Timestamp muduo::timedifference() free function C++ Java 11.5 boost::function boost::bind boost::function boost::bind boost::function boost::bind std::tr1 C++11 C++ Scott Meyers [EC3 35] boost::function boost:bind function/bind class hierarchy class class
102 C++ class class class C++ wrapper adapter 13 C++ : boost::function boost::bind x A x is-a A B x is more like a B C++ interfaces 14 Ruby duck typing Google Go 15 tag object operations 13 Linus 2007 C++ C
103 11.5 boost::function boost::bind 449 C++ better C data abstraction OO GP object based global function C++ Handler class onconnect() ondisconnect() onmessage() ontimer() override C++ MyHandler Handler MyHandler delete override OO framework Java 16 C++ GC MyHandler delete this; MyHandler TCP MyHandler HandlerFactory MyHandlerFactory C TR1 C++11 boost::function + boost::bind std::tr1::function + std::tr1::bind C++11 std::function + std::bind muduo boost::function TCP IO boost::bind class boost::function muduo muduo 16 Java 8 Closure C# delegate
104 第 11 章 450 反思 C++ 面向对象与虚函数 言归正传 说说 boost::function 和 boost::bind 取代虚函数的具体做法 基本用途 boost::function 就像 C# 里的 delegate 可以指向任何函数 包括成员函数 当 用 bind 把某个成员函数绑到某个对象上时 我们得到了一个 closure 闭包 例如 class Foo { public: void methoda(); void methodint(int a); void methodstring(const string& str); }; class Bar { public: void methodb(); }; boost::function<void()> f1; // 无参数 无返回值 Foo foo; f1 = boost::bind(&foo::methoda, &foo); f1(); // 调用 foo.methoda(); Bar bar; f1 = boost::bind(&bar::methodb, &bar); f1(); // 调用 bar.methodb(); f1 = boost::bind(&foo::methodint, &foo, 42); f1(); // 调用 foo.methodint(42); f1 = boost::bind(&foo::methodstring, &foo, "hello"); f1(); // 调用 foo.methodstring("hello") // 注意 bind 拷贝的是实参类型 (const char*) 不是形参类型 (string) // 这里形参中的 string 对象的构造发生在调用 f1 的时候 而非 bind 的时候 // 因此要留意 bind 的实参 (cosnt char*) 的生命期 它应该不短于 f1 的生命期 // 必要时可通过 bind(&foo::methodstring, &foo, string(atempbuf)) 来保证安全 boost::function<void(int)> f2; // int 参数 无返回值 f2 = boost::bind(&foo::methodint, &foo, _1); f2(53); // 调用 foo.methodint(53); 如果没有 boost::bind 那么 boost::function 就什么都不是 而有了 bind 同 一个类的不同对象可以 delegate 给不同的实现 从而实现不同的行为 孟岩 简直 就无敌了 Linux 多线程服务端编程 使用 muduo C++ 网络库 (excerpt)
105 11.5 boost::function boost::bind class C++ 1 OO Thread base class Thread::run() derived class run() Thread Java Thread class class method helper class(es) OO boost::function Thread ThreadCallback ThreadCallback Thread Thread::start() Java Thread Runnable C# Thread delegate ThreadStart boost::thread // boost::function Thread class class Thread { public: typedef boost::function<void()> ThreadCallback; Thread(ThreadCallback cb) : cb_(cb) { } void start() { /* some magic to call run() in new created thread */ } private: void run() { cb_(); } ThreadCallback cb_; //... };
106 C++ class Foo // { public: void runinthread(); void runinanotherthread(int) }; Foo foo; Thread thread1(boost::bind(&foo::runinthread, &foo)); Thread thread2(boost::bind(&foo::runinanotherthread, &foo, 43)); thread1.start(); // thread2.start(); 2 boost::function NetServer class EchoService NetServer main() 17 network library class Connection; class NetServer : boost::noncopyable { public: typedef boost::function<void (Connection*)> ConnectionCallback; typedef boost::function<void (Connection*, const void*, int len)> MessageCallback; NetServer(uint16_t port); ~NetServer(); void registerconnectioncallback(const ConnectionCallback&); void registermessagecallback(const MessageCallback&); void sendmessage(connection*, const void* buf, int len); private: //... }; network library user code class EchoService { public: // NetServer::sendMessage typedef boost::function<void(connection*, const void*, int)> SendMessageCallback; EchoService(const SendMessageCallback& sendmsgcb) : sendmessagecb_(sendmsgcb) // boost::function { } 17 muduo
107 11.5 boost::function boost::bind 453 // NetServer::MessageCallback void onmessage(connection* conn, const void* buf, int size) { printf("received Msg from Connection %d: %.*s\n", conn->id(), size, (const char*)buf); sendmessagecb_(conn, buf, size); // echo back } // NetServer::ConnectionCallback void onconnection(connection* conn) { printf("connection from %s:%d is %s\n", conn->ipaddr(), conn->port(), conn->connected()? "UP" : "DOWN"); } private: SendMessageCallback sendmessagecb_; }; // int main() { NetServer server(7); EchoService echo(bind(&netserver::sendmessage, &server, _1, _2, _3)); server.registermessagecallback( bind(&echoservice::onmessage, &echo, _1, _2, _3)); server.registerconnectioncallback( bind(&echoservice::onconnection, &echo, _1)); server.run(); } user code class concept OO attribute/annotation JUnit 3.x void test*() JUnit 4.x NUnit 2.x annotation/attribute test case
108 C++ closure closure boost::function+boost::bind class object-based closure OO Factory Method boost::function<base* ()> Strategy Strategy ConcreteStrategyA ConcreteStrategyB boost::function Command boost::function Command Template Method boost::function boost::function 23 C closure paradigm EchoService EchoService SendMessageCallback DataSink
109 11.5 boost::function boost::bind 455 AbstractDataSink interface sendmessage() class NetDataSink MockDataSink EchoService AbstractDataSink* SendMessageCallback boost::bind() MockServer OO public boost::noncopyable boost::enable_ shared_from_this 1.11 enable_shared_from_this IO multiplexing select() POSIX poll() Linux epoll() FreeBSD kqueue() NetLoop base class classes switch-case Penguin Bird Bird virtual function fly() interface Flyable Runnable Runnable Flyable Runnable interface method interface tag boost::function
110 C++ class Penguin // { public: void run(); void swim(); }; class Sparrow // { public: void fly(); void run(); }; // boost::function typedef boost::function<void()> FlyCallback; typedef boost::function<void()> RunCallback; typedef boost::function<void()> SwimCallback; // run fly class class Foo { public: Foo(FlyCallback flycb, RunCallback runcb) : flycb_(flycb), runcb_(runcb) { } private: FlyCallback flycb_; RunCallback runcb_; }; // run swim class class Bar { public: Bar(SwimCallback swimcb, RunCallback runcb) : swimcb_(swimcb), runcb_(runcb) { } private: SwimCallback swimcb_; RunCallback runcb_; }; int main() { Sparrow s; Penguin p; // Foo Bar Foo foo(bind(&sparrow::fly, &s), bind(&sparrow::run, &s)); Bar bar(bind(&penguin::swim, &p), bind(&penguin::run, &p)); }
111 4
112
113 A Sockets API TCP/IP A.1.5 x86-64 Linux Sockets API PC PC Windows W. Richard Stevents TCP TCP TCP A.1 561
114 562 A A.1.1 Sockets API Sockets API 2005 C# PC C# PDA PDA TCP PDA PC 42 PC PDA PC 7 PC FTP PC PDA single point of failure TCP read/write blocking 2010 muduo Sockets API Reactor C++ Sockets API muduo Sockets API TCP Sockets API TCP TCP Sockets API A.1.5
115 A A.1.2 TCP UDP client library server libmemcached memcached libpq PostgreSQL Servlet HTTP RPC TCP/IP troubleshooting library framework Sockets API Sockets API strace Sockets API TCP/IP tcpdump A.1.3 Linux 10 FreeBSD FreeBSD Linux epoll FreeBSD kqueue C10k Linux 1 Linux bug work around FreeBSD Linux Linux A.1.4 Windows Linux FreeBSD Solaris 1
116 564 A AIX HP-UX Linux POSIX Linux SO_NOSIGPIPE Linux pipe(2) FreeBSD muduo Windows libevent libuv Java Netty A.1.5 big topic ping ping bug 1. firmware TCP/IP 4. HTTP FTP DNS SMTP POP3 NFS 5. HAProxy squid varnish Web load balancer 6. ZooKeeper memcached POP3 SMTP
117 A TCP/IP Sockets API muduo libevent muduo Netty gevent muduo A.1.6 HTTP HTTP 1.1 bug spec HTTP TCP accept 2 accept HAProxy lighttpd CPU one loop per thread httpd Nginx lighttpd 2 Linux for_servers_with_high_connection%20rates.pdf
118 566 A IO bound CPU Disk IO trade-off echo qps 1ms qps IO A master NAT TCP HTTP proxy HTTP server Web crawler HTTP HTTP proxy 3 3
119 A Web browser HTTP server 4 wget A bit malloc memcached malloc memory pool
120 568 A Linux Kernel PC 3% 5% STL new/delete premature optimization A.1.9 RFC daytime HTTP 1.0 echo chargen TIME_WAIT hold TIME_WAIT TIME_WAIT (s) TIME_WAIT buggy TIME_WAIT XML JSON Protobuf
121 A race condition p. 348 snapshot delta 30 end-to-end principle happens-before relationship A STL STL STL STL STL TCP/IP 3. TCP/IP stack UNIX TCP/IP TCP/IP manpage manpage TCP/IP Linux TCP/IP 1. TCP self-connection 8 2. Linux bug TCP TCP window clamping bug work around manpage ACE
122 570 A error code ephemeral port backlog connect manpage TCP/IP TCP/IP TCP TCP/IP send_packet() on_receive_packet() on_timer() libnet libpcap TCP/IP TCP/IP lwip Mini/Tiny/Toy/Trivial/Yet-Another TCP/IP TUN/TAP TCP/IP D Sockets API FTDI USB-SPI ENC28J60 TCP/IP stack IP ICMP Echo TCP 3000 UDP DNS A.1.11 TCP echo chat proxy echo echo HTTP chat a b fork()-per-connection b c b a c
123 A proxy 7.13 TCP A.1.12 Sockets API IPython muduo 9 Sockets API IPython IO C TCP epoll $ ipython In [1]: import socket, select In [2]: s = socket.socket(socket.af_inet, socket.sock_stream) In [3]: s.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1) In [4]: s.bind(('', 5000)) In [5]: s.listen(5) In [6]: client, address = s.accept() # client.fileno() == 4 In [7]: client.recv(1024) Out[7]: 'Hello\n' # In [8]: epoll = select.epoll() In [9]: epoll.register(client.fileno(), select.epollin) # In [10]: epoll.poll(60) Out[10]: [(4, 1)] # # 4 select.epollin == 1 In [11]: client.recv(1024) # Out[11]: 'World\n' In [12]: client.setblocking(0) # In [13]: client.recv(1024) # EAGAIN == 11 error: [Errno 11] Resource temporarily unavailable In [14]: epoll.poll(60) Out[14]: [(4, 1)] In [15]: client.recv(1024) Out[15]: 'Bye!\n' # epoll_wait() # In [16]: client.close() nc 9
124 572 A $ nc localhost 5000 Hello <enter> World <enter> Bye! <enter> muduo log strace netcat/tempest/ipython tcpdump muduo Reactor Linux C++ IO 4000 A.1.13 TCP TCP Effective TCP/IP Programming 9 Realize That TCP Is a Reliable Protocol, Not an Infallible Protocol TCP 7.5 Google Protobuf check sum IP header check sum TCP header check sum CRC32 TCP IP header TCP header checksum 16-bit check sum 16-bit integers checksum sum 16-bit checksum CRC32 CRC A-1 client server TCP segment segment IP packet ethernet frame A-1 a router ethernet frame b c server d CRC a b c d TCP header checksum payload router NAT NAT c a d payload TCP header checksum
125 A client a server d switch 1 switch 2 b c router A-1 IP bit payload check sum check sum ethernet CRC When the CRC and TCP checksum disagree The Limitations of the Ethernet CRC and TCP/IP checksums for error detection 10 Amazon S bit check sum Google 12 MD5 end-to-end principle A.2 Unix W. Richard Stevens 6 [APUE] UNIX TCP/IP
126 574 A [UNPv2] [APUE] IPC TCP/IP TCP/IP TCP/IP Illustrated, Vol. 1: The Protocols TCP/IP TCPv1 TCPv1 13 TCPv1 TCP/IP W. Richard Stevens TCP/IP tcpdump TCP TCP packet TCP 1. Positive acknowledgement with retransmission 2. Flow control using sliding window Nagle 3. Congestion control slow start congestion avoidance fast retransmit TCP TCP flow control TCP connection TCPv Mbit 100Mbit switch hub 1Gbit 13
127 A Gbit TCP flow control TCP IPv6 TCP window scale option TCP timestamps option TCP selective ack option Linux tcpdump TCP TCPv Unix Network Programming, Vol. 1: Networking API XTI UNP W. Richard Stevens UNP 2 UNP 3 UNP Sockets API Sockets API W. Richard Stevens UNP 2 14 I have found when teaching network programming that about 80% of all network programming problems have nothing to do with network programming, per se. That is, the problems are not with the API functions such as accept and select, but the problems arise from a lack of understanding of the underlying network protocols. For example, I have found that once a student understands TCP s three-way handshake and four-packet connection termination, many network programming problems are immediately understood. TCP/IP Nagle UNP 3 UNP UNIX UNP UDP TCP IPv4 IPv
128 576 A MFC Scott Meyers Effective C++ W. Richard Stevens Jeffrey Richter CRC32 check sum check sum CRC CRC CRC CRC zlib UNP Sockets Out-of-Band Data Signal-Driven IO UNP UNP daytime echo TCP
129 A W. Richard Stevens UNP UNP Unix accept() + fork() C10k TCPv1 UNP TCPv1 UNP APUE Effective TCP/IP Programming W. Richard Stevens W. Richard Stevens UNP Effective TCP/IP Programming 6 TCP TCP TCP/IP Illustrated, Vol. 2: The Implementation TCPv BSD TCP/IP C Gary Wright mbuf IP ICMP IP IGMP IP Sockets ARP 3/4 TCP TCP TCPv2 IGMP IP host-to-host IP packet
130 578 A TCP TCP/IP stack inode BSD MiB VAX TCP/IP mbuf buffer TCP/IP 4.4BSD timer Linux TCP/IP Linux TCP/IP 3 Pattern-Oriented Software Architecture Volume 2: Patterns for Concurrent and Networked Objects POSA2 UNP UNP Sockets API POSA2 library/framework event-driven libevent Java Netty Java Mina Perl POE Python Twisted POSA2 C++ RAII
131 B C++ Primer 4 C++ C++ Primer 4 34 B.1 C Stanley Lippman C++ C++ Java C# Python C++ C++ 1 C C++ 10% 10% Google 2 C++ Bjarne Stroustrup C C Milo Yip C++ Unreal/Source Havok/FMOD C
132 580 B C++ Primer 4 C++ GC C++ 5 C++ Java C# C++ Bjarne Stroustrup C++ system programming 6 infrastructure C++ 7 Herb Sutter 8 C++ efficiency flexibility 9 abstraction productivity 10 C++ is about efficient programming with abstractions C++ 11 C & inline int find_longest(const std::vector<std::string>& words) { // std::max_element(words.begin(), words.end(), LengthCompare()); } CPU C++ memory layout locality of reference 5 C++ clean up 6 CPU 7 Software Development for Infrastructure 8 Herb Sutter C++ and Beyond 2011 Why C++? 9 just-in-time compilation 10 Stanley Lippman Linux 1970 C++ C++ 11 Ulrich Drepper Stop Underutilizing Your Computer SIMD 12 Technical Report on C++ Performance 13 Scott Meyers Effective C++ in an Embedded Environment
133 B.2 C memory hierarchy 14 Scott Meyers CPU Caches and Why You Care 15 Herb Sutter Machine Architecture 16 / GC 17 C++ C Java Python TIOBE C++ Java B.2 C++ C++ features Google 18 C++ C C++ C++ Bjarne Stroustrup The C++ Programming Language Stanley Lippman C++ Primer C++ 21 C++ Primer 10 C++ 14 std::list O(1) std::vector O(N) vector compact vector list vector Bjarne Stroustrup Abstraction and the C++ machine model C++ Java bs/abstraction-and-machine.pdf 18 50% 19 C++ 20 Java C# Python 21 C++ Primer 3/e
134 582 B C++ Primer 4 C++ C++ Primer 3 C++ Primer Barbara Moo C++ Primer 4 C++ Huffman C++ C++ syntax semantics C++ STL C++ 23 C++ C C++ C++ Primer 4 C C++ C++ C C++ Primer 4 C++ C C Bjarne Stroustrup Programming Principles and Practice Using C++ use only the 4th edition 23 C++ Primer 4/e Accelerated C++ C : C 25 iostream locale/facet 26 Stanley Lippman Virtual base class support wanders off into the Byzantine... The material is simply too esoteric to warrant discussion...
135 B.2 C C++ Primer 4 C++ 3 string vector class string C++ Primer Liskov C++ Primer C++ 27 C C++11 TR1 28 C C++ C++ Primer 4 C++ GNU G++ Visual C++ 30 C++ C++ C++ C++ 31 C++ C++ C++ C C++ C++ C C++ 28 TR C++ bind/function 29 C++ Primer 5 C G++ Linux Unix Visual C++ Windows C++ Intel C++ Linux G++ Windows Visual C++ 31 Cfront 32 C++
136 584 B C++ Primer 4 C++ C++ 33 C++ 34 C++ module package C C++ 35 vector<t> vector int std::string B B-1 36 calculate() + Node 3 * NumberNode BinaryNode 2 4 AddNode MultiplyNode B-1 33 G++ 4.x 32-bit 64-bit 64-bit C++ Visual C Express Visual C C++ C std::vector<int> 36 Packrat
137 B B-2 BinaryNode<std::plus<double> > BinaryNode<std:: multiplies<double> > BinaryNode<T> Node NumberNode BinaryNode<T> B Handle C++ C++ C++ 37 C++ C++ 38 Google Protobuf leveldb PCRE C++ muduo Chromium Google C++ STL Boost C++ C++ C Java C++ B.3 C++ C++ Primer C++ Effective C [EC3] Scott Meyers
138 586 B C++ Primer 4 C++ C++ C++ Primer C++ Effective C++ 3 Effective C++ 3 C C++ C++ override class 41 C++ idiom RAII 42 TCP RAII C C++ delete C++ Effective C C++ C 44 TR1 bind/function 45 Stephan T. Lavavej PPT 40 Andrew Koenig Teaching C++ Badly: Introduce Constructors and Destructors at the Same Time 41 std::string std::vector boost::shared_ptr class 42 heap 43 TR1 shared_ptr weak_ptr boost::scoped_ptr 44 Java 7 try-with-resources Python with C# using 45 function/bind
139 B TR STL 48 C++ Primer C++ C++ 49 [CCS] concept model refinement C++ STL STL 50 C++ type traits C++ 51 C 52 C++ C++ C++ Effective C C++ C/C Matthew Austern 49 Herb Sutter 50 Iterator 51 C C
140 588 B C++ Primer 4 C++ 35 class 43 pimpl C++ 56 swap() swap() 59 #include using 73 by value by reference 76 vector 79 value smart pointer 5 entity class value class base class trait class policy class exception class 33 class monolithic class 37 public 57 class namespace C++ Google C++ 54 LLVM 55 B
141 B PDF C++ 15% 56 5 C TR1 TR1 URL C++ [CCS] soxxxxxx PDF [email protected] lower_bound upper_bound 57 Scott Meyers C++11
142
143 C Boost Boost C++ Boost 1 C++ STL Boost vector map shared_ptr vector map shared_ptr weak_ptr C++ Boost Boost Boost noncopyable scoped_ptr static_assert Boost date_time 2 circular_buffer function/bind shared_ptr C++ delete lexical_cast Boost Boost boost::date_time muduo::timezone 591
144 592 C Boost regex RegEx class class RegEx regex immutable mutable basic_regex match_results match_regex regex Donald Knuth Coders at Work C/C++ C strlen strcpy strcmp C++ complex string vector class STL STL Boost Boost Boost Boost generic programming concept model refinement Boost.Threads STL Boost Boost.Preprocessor C++ Lua Boost.Proto C++ ANTLR parser Boost.Spirit Boost C++
145 D TCP TCP 1 IP TCP TCP/IP IPv6 TCP TCP :8765 A B B frame A 10 TCP B 100 TCP Linux socket(2) accept(2) TCP file descriptor dup() fork() TCP TCP/IP TCP 1. TCP TCP accept(2)
146 594 D TCP 2. TCP TCP connect(2) Sockets API TCP/IP TCP/IP TCP TCP TCP IP packet TCP 1 TCP faketcp 1a. TCP IP packet SYN TCP segment 1b. SYN ACK TCP segment 1c. ACK segment faketcp TCP faketcp TCP/IP IP packet Ethernet frame faketcp IP:PORT TCP faketcp 2 TCP faketcp 2a. SYN TCP segment 2b. SYN ACK TCP segment 2c. ACK segment faketcp SYN SYN+ACK TCP faketcp faketcp TCP faketcp TCP
147 595 faketcp faketcp TCP recipes/faketcp make Ubuntu Linux PC hostname atom D-1 router atom / Ethernet D-1 A TUN/TAP TCP/IP D /24 faketcp.x TUN router atom / Ethernet D-2 atom /dev/net/tun tun /24 faketcp /24 atom ~ IP packet faketcp faketcp IP atom IP packet
148 596 D TCP ICMP echo ping faketcp recipes/faketcp/ icmpecho.cc ICMP echo request icmp_input() recipes/faketcp/faketcp.cc sudo./icmpecho allocted tunnel interface tun $ sudo ifconfig tun /24 $ sudo tcpdump -i tun $ ping $ ping $ ping X IP ping TCP SYN TCP segment RST segment recipes/faketcp/rejectall.cc 3 faketcp./rejectall 3 $ nc $ nc $ nc IP TCP TCP SYN TCP segment SYN+ACK FIN segment FIN+ACK recipes/faketcp/acceptall.cc 3 faketcp./acceptall nc X IP port 4 netstat -tpn nc netstat Send-Q
149 597 TCP payload TCP segment ACK recipes/faketcp/discardall.cc 3 faketcp./discardall nc X IP port 4 netstat -tpn 0 2 TCP 1 atom recipes/faketcp/connectmany.cc sudo./connectmany : allocted tunnel interface tun0 press enter key to start connecting : $ sudo ifconfig tun /24 $ sudo tcpdump -i tun TCP httpd muduo echo discard listen netstat -tpn TCP TCP/IP A TCP mini tcp stack IPv IP TCP end points end point {ip, port} end point end point 2 48 IP 2 32 IP 2 16
150 598 D TCP NAT Linux
151 [JCP] [RWC] [APUE] [UNP] [UNPv2] [TCPv1] Brian Goetz. Java Concurrency in Practice. Addison-Wesley 2006 Bryan Cantrill and Jeff Bonwick. Real-World Concurrency. ACM Queue W. Richard Stevens and Stephen A. Rago. Advanced Programming in the UNIX Environment 2nd ed. Addison-Wesley 2005 UNIX W. Richard Stevens. UNIX 1 API Unix Network Programming vol. 1 The Sockets Networking API 3rd ed UNIX W. Richard Stevens. Unix Network Programming vol. 2 Interprocess Communications 2nd ed. Prentice Hall 1999 UNIX W. Richard Stevens. TCP/IP Illustrated vol. 1: The Protocols. Addison- Wesley 1994 TCP/IP [TCPv2] W. Richard Stevens. TCP/IP Illustrated vol. 2: The Implementation. Addison-Wesley 1995 TCP/IP [CC2e] [EC3] [ESTL] Steve McConnell Code Complete 2nd ed Scott Meyers. Effective C Scott Meyers. Effective STL. Addison-Wesley
152 600 [CCS] [LLL] [WELC] [TPoP] [K&R] [ExpC] Herb Sutter and Andrei Alexandrescu. C C++ Coding Standards: 101 Rules Guidelines and Best Practices Michael Feathers Working Effectively with Legacy Code Brian W. Kernihgan and Rob Pike The Practice of Programming Brian W. Kernighan and Dennis M. Ritchie. The C Programming Language 2nd ed. Prentice Hall 1988 C Peter van der Linden. Expert C Programming: Deep C Secrets. Prentice Hall 1994 [CS:APP] Randal E. Bryant and David R. O Hallaron Computer Systems: A Programmer s Perspective [D&E] [ERL] [DCC] [Gr00] [jjhou02] Bjarne Stroustrup. C The Design and Evolution of C++ Joe Armstrong. Erlang Programming Erlang Luiz A. Barroso and Urs Hölzle. The Datacenter as a Computer. Morgan and Claypool Publishers Jeff Grossman. A Technique for Safe Deletion with Object Locking. More C++ Gems. Robert C. Martin (ed.). Cambridge University Press Memory Pool [Alex10] Andrei Alexandrescu. Scalable Use of the STL. C++ and Beyond
W. Richard Stevens UNIX Sockets API echo Sockets TCP OOB IO C struct C/C++ UNIX fork() select(2)/poll(2)/epoll(4) IO IO CPU 100% libevent UNIX CPU IO
Linux muduo C++ ([email protected]) 2012-09-30 C++ TCP C++ x86-64 Linux TCP one loop per thread Linux native muduo C++ IT 5 C++ muduo 2 C++ C++ Primer 4 W. Richard Stevens UNIX Sockets API echo Sockets
[JCP] class interleaving C++ class std:: string std::vector std::map class MutexLock MutexLockGuard C MutexLock critical section
1 synchronization primitives mutex race condition C++ Boost shared_ptr weak_ptr 1 Observer 2009 12 C++ C++ Observer 1.1 C++ race condition race condition C++ shared_ptr C++ 1 class TR1 std::tr1 C++11 3
1 C++ 2 Bjarne Stroustrup C++ (system programming) 6 (infrastructure) C++ 7 Herb Sutter 8 C++ (efficiency) (flexibility) 9 (abstraction) (productivity
1 C++ 1 C++ Primer C++ ([email protected]) 2012-7-11 Creative Commons - - 3.0 Unported (cc by-nc-nd) http://creativecommons.org/licenses/by-nc-nd/3.0/ 1 C++ 2009 Stanley Lippman C++ C++ Java/C#/Python
Windows RTEMS 1 Danilliu MMI TCP/IP QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos eco
Windows RTEMS 1 Danilliu MMI TCP/IP 80486 QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos ecos Email www.rtems.com RTEMS ecos RTEMS RTEMS Windows
提问袁小兵:
C++ 面 试 试 题 汇 总 柯 贤 富 管 理 软 件 需 求 分 析 篇 1. STL 类 模 板 标 准 库 中 容 器 和 算 法 这 部 分 一 般 称 为 标 准 模 板 库 2. 为 什 么 定 义 虚 的 析 构 函 数? 避 免 内 存 问 题, 当 你 可 能 通 过 基 类 指 针 删 除 派 生 类 对 象 时 必 须 保 证 基 类 析 构 函 数 为 虚 函 数 3.
untitled
Lwip Swedish Institute of Computer Science February 20, 2001 Adam Dunkels [email protected] (QQ: 10205001) (QQ: 329147) (QQ:3232253) (QQ:3232253) QQ ARM TCPIP LCD10988210 LWIP TCP/IP LWIP LWIP lwip API lwip
智力测试故事
II 980.00 ... 1... 1... 1... 2... 2... 2... 3... 3... 3... 3... 4... 4... 5... 5... 6... 6... 7... 7... 8... 8... 8... 9... 9...10...10...10 I II...11...11...11...12...13...13...13...14...14...14...15...15...15...16...16...17...17...18...18...19...19...19...19...20...20...21...21...21
I. 1-2 II. 3 III. 4 IV. 5 V. 5 VI. 5 VII. 5 VIII. 6-9 IX. 9 X XI XII. 12 XIII. 13 XIV XV XVI. 16
125-0834I/1405/GH I. 1-2 II. 3 III. 4 IV. 5 V. 5 VI. 5 VII. 5 VIII. 6-9 IX. 9 X. 10-11 XI. 11-12 XII. 12 XIII. 13 XIV. 14-15 XV. 15-16 XVI. 16 I. * ++p ++ p ++ ++ * ++p ++ ++ ++p 1 2 ++ ++ ++ ++ ++ I.
30,000,000 75,000,000 75,000, (i) (ii) (iii) (iv)
30,000,000 75,000,000 75,000,000 24 (i) (ii) (iii) (iv) # * 1,800,000 1,800,000 15% 3,400,000 3,400,000 15% 4,200,000 4,200,000 10% 8,600,000 8,600,000 10% 12,600,000 12,600,000 88% 10% 16,000,000 16,000,000
Socket Socket TcpClient Socket.Connect TcpClient.Connect Socket.Send / Receive NetworkStream 6-5
6 6-1 6-2 Socket 6-2-1 Socket 6-2-2 TcpClient 6-3 6-3-1 Socket.Connect 6-3-2 TcpClient.Connect 6-4 6-4-1 Socket.Send / Receive 6-4-2 NetworkStream 6-5 6-5-1 Socket.Close 6-5-2 TcpClient.Close 6-6 DateTime
新版 明解C++入門編
511!... 43, 85!=... 42 "... 118 " "... 337 " "... 8, 290 #... 71 #... 413 #define... 128, 236, 413 #endif... 412 #ifndef... 412 #if... 412 #include... 6, 337 #undef... 413 %... 23, 27 %=... 97 &... 243,
Microsoft Word - 物件導向編程精要.doc
Essential Object-Oriented Programming Josh Ko 2007.03.11 object-oriented programming C++ Java OO class object OOP Ruby duck typing complexity abstraction paradigm objects objects model object-oriented
概述
OPC Version 1.6 build 0910 KOSRDK Knight OPC Server Rapid Development Toolkits Knight Workgroup, eehoo Technology 2002-9 OPC 1...4 2 API...5 2.1...5 2.2...5 2.2.1 KOS_Init...5 2.2.2 KOS_InitB...5 2.2.3
_汪_文前新ok[3.1].doc
普 通 高 校 本 科 计 算 机 专 业 特 色 教 材 精 选 四 川 大 学 计 算 机 学 院 国 家 示 范 性 软 件 学 院 精 品 课 程 基 金 青 年 基 金 资 助 项 目 C 语 言 程 序 设 计 (C99 版 ) 陈 良 银 游 洪 跃 李 旭 伟 主 编 李 志 蜀 唐 宁 九 李 涛 主 审 清 华 大 学 出 版 社 北 京 i 内 容 简 介 本 教 材 面 向
2 2 3 DLight CPU I/O DLight Oracle Solaris (DTrace) C/C++ Solaris DLight DTrace DLight DLight DLight C C++ Fortran CPU I/O DLight AM
Oracle Solaris Studio 12.2 DLight 2010 9 2 2 3 DLight 3 3 6 13 CPU 16 18 21 I/O DLight Oracle Solaris (DTrace) C/C++ Solaris DLight DTrace DLight DLight DLight C C++ Fortran CPU I/O DLight AMP Apache MySQL
FY.DOC
高 职 高 专 21 世 纪 规 划 教 材 C++ 程 序 设 计 邓 振 杰 主 编 贾 振 华 孟 庆 敏 副 主 编 人 民 邮 电 出 版 社 内 容 提 要 本 书 系 统 地 介 绍 C++ 语 言 的 基 本 概 念 基 本 语 法 和 编 程 方 法, 深 入 浅 出 地 讲 述 C++ 语 言 面 向 对 象 的 重 要 特 征 : 类 和 对 象 抽 象 封 装 继 承 等 主
untitled
1 Outline 數 料 數 數 列 亂數 練 數 數 數 來 數 數 來 數 料 利 料 來 數 A-Z a-z _ () 不 數 0-9 數 不 數 SCHOOL School school 數 讀 school_name schoolname 易 不 C# my name 7_eleven B&Q new C# (1) public protected private params override
ebook
3 3 3.1 3.1.1 ( ) 90 3 1966 B e r n s t e i n P ( i ) R ( i ) W ( i P ( i P ( j ) 1) R( i) W( j)=φ 2) W( i) R( j)=φ 3) W( i) W( j)=φ 3.1.2 ( p r o c e s s ) 91 Wi n d o w s Process Control Bl o c k P C
Scott Effective C++ C++ C++ Roger Orr OR/2 ISO C++ Effective Modern C++ C++ C++ Scoot 42 Bart Vandewoestyne C++ C++ Scott Effective Modern C++ Damien
Effective Modern C++ C++ C++ C++11/C++14 C++ Scott Meyers Gerhard Kreuzer Siemens AG Effective Modern C++ Effective Modern C++ Andrei Alexandrescu Facebook Modern C++ Design C++ C++ Nevin Liber DRW Trading
WWW PHP
WWW PHP 2003 1 2 function function_name (parameter 1, parameter 2, parameter n ) statement list function_name sin, Sin, SIN parameter 1, parameter 2, parameter n 0 1 1 PHP HTML 3 function strcat ($left,
ebook140-9
9 VPN VPN Novell BorderManager Windows NT PPTP V P N L A V P N V N P I n t e r n e t V P N 9.1 V P N Windows 98 Windows PPTP VPN Novell BorderManager T M I P s e c Wi n d o w s I n t e r n e t I S P I
Microsoft Word - Final Chi-Report _PlanD-KlnEast_V7_ES_.doc
九 龍 東 商 業 的 統 計 調 查 - 行 政 摘 要 - 2011 年 5 月 統 計 圖 行 政 摘 要...1 圖 I: 在 不 同 地 區 及 樓 宇 類 別 的 數 目 及 比 例...9 圖 II: 影 響 選 擇 地 點 的 因 素 的 重 要 程 度 對 比 就 現 時 所 在 地 點 各 項 因 素 的 滿 意 程 度...20 圖 III: 影 響 選 擇 樓 宇 的 因 素
奇闻怪录
... 1... 1... 2... 3... 3... 4... 4... 5... 5... 6... 8... 9... 10... 10... 11... 11... 13... 13... 14... 14... 15... 16... 17... 21 I ... 22... 23... 23... 24... 25... 25... 26... 27... 28... 29 UFO...
Microsoft Word - John_Ch_1202
新 约 圣 经 伴 读 约 翰 福 音 目 录 说 明..I 序 言 : 圣 经 中 神 圣 启 示 的 三 层.II 按 时 分 粮 的 原 则..VIII 纲 目 XI 第 一 章..1 第 二 章 13 第 三 章 25 第 四 章 37 第 五 章 49 第 六 章 61 第 七 章 73 第 八 章 85 第 九 章 97 第 十 章..109 第 十 一 章..121 第 十 二 章..133
全唐诗50
... 1... 1... 2... 2... 3... 3... 3... 4... 4... 5... 5... 6... 6... 6... 7... 7... 7... 8... 8... 8... 9 I II... 9...10...10...10...11...11...11...12...12...12...13...14...14...15...15...16...16...16...17,...17...18...18...19...19...19
mvc
Build an application Tutor : Michael Pan Application Source codes - - Frameworks Xib files - - Resources - ( ) info.plist - UIKit Framework UIApplication Event status bar, icon... delegation [UIApplication
Symantec™ Sygate Enterprise Protection 防护代理安装使用指南
Symantec Sygate Enterprise Protection 防 护 代 理 安 装 使 用 指 南 5.1 版 版 权 信 息 Copyright 2005 Symantec Corporation. 2005 年 Symantec Corporation 版 权 所 有 All rights reserved. 保 留 所 有 权 利 Symantec Symantec 徽 标 Sygate
Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc
References (Section 5.2) Hsuan-Tien Lin Deptartment of CSIE, NTU OOP Class, March 15-16, 2010 H.-T. Lin (NTU CSIE) References OOP 03/15-16/2010 0 / 22 Fun Time (1) What happens in memory? 1 i n t i ; 2
C/C++ - 字符输入输出和字符确认
C/C++ Table of contents 1. 2. getchar() putchar() 3. (Buffer) 4. 5. 6. 7. 8. 1 2 3 1 // pseudo code 2 read a character 3 while there is more input 4 increment character count 5 if a line has been read,
软件测试(TA07)第一学期考试
一 判 断 题 ( 每 题 1 分, 正 确 的, 错 误 的,20 道 ) 1. 软 件 测 试 按 照 测 试 过 程 分 类 为 黑 盒 白 盒 测 试 ( ) 2. 在 设 计 测 试 用 例 时, 应 包 括 合 理 的 输 入 条 件 和 不 合 理 的 输 入 条 件 ( ) 3. 集 成 测 试 计 划 在 需 求 分 析 阶 段 末 提 交 ( ) 4. 单 元 测 试 属 于 动
SL2511 SR Plus 操作手冊_單面.doc
IEEE 802.11b SL-2511 SR Plus SENAO INTERNATIONAL CO., LTD www.senao.com - 1 - - 2 - .5 1-1...5 1-2...6 1-3...6 1-4...7.9 2-1...9 2-2 IE...11 SL-2511 SR Plus....13 3-1...13 3-2...14 3-3...15 3-4...16-3
施 的 年 度 維 修 工 程 已 於 4 月 15 日 完 成, 並 於 4 月 16 日 重 新 開 放 給 市 民 使 用 ii. 天 水 圍 游 泳 池 的 年 度 維 修 工 程 已 於 3 月 31 日 完 成, 並 於 4 月 1 日 重 新 開 放 給 市 民 使 用 iii. 元
地 委 會 文 件 2016/ 第 25 號 ( 於 6.5.2016 會 議 討 論 ) 康 樂 及 文 化 事 務 署 在 元 朗 區 內 舉 辦 的 康 樂 體 育 活 動 及 設 施 管 理 綜 合 匯 報 (2016 年 5 月 號 報 告 ) 目 的 本 文 件 旨 在 向 各 委 員 匯 報 康 樂 及 文 化 事 務 署 ( 康 文 署 ) 於 2016 年 2 月 至 5 月 在
普 通 高 等 教 育 十 二 五 重 点 规 划 教 材 计 算 机 系 列 中 国 科 学 院 教 材 建 设 专 家 委 员 会 十 二 五 规 划 教 材 操 作 系 统 戴 仕 明 姚 昌 顺 主 编 姜 华 张 希 伟 副 主 编 郑 尚 志 梁 宝 华 参 编 参 编 周 进 钱 进
科 学 出 版 社 普 通 高 等 教 育 十 二 五 重 点 规 划 教 材 计 算 机 系 列 中 国 科 学 院 教 材 建 设 专 家 委 员 会 十 二 五 规 划 教 材 操 作 系 统 戴 仕 明 姚 昌 顺 主 编 姜 华 张 希 伟 副 主 编 郑 尚 志 梁 宝 华 参 编 参 编 周 进 钱 进 参 编 北 京 内 容 简 介 本 书 由 浅 入 深 系 统 全 面 地 介 绍
C/C++ - 文件IO
C/C++ IO Table of contents 1. 2. 3. 4. 1 C ASCII ASCII ASCII 2 10000 00100111 00010000 31H, 30H, 30H, 30H, 30H 1, 0, 0, 0, 0 ASCII 3 4 5 UNIX ANSI C 5 FILE FILE 6 stdio.h typedef struct { int level ;
投影片 1
9 1 9-1 Windows XP Windows Server 2003 Mac OS Linux, 都 (OS, Operating System ) 2 3 , 來, 行 3 理 行 4 ,, (UI, User Interface), 滑, 令 列 (CLI, Command-Line Interface) (GUI, Graphical User Interface) 2 5 令 列,
ebook140-8
8 Microsoft VPN Windows NT 4 V P N Windows 98 Client 7 Vintage Air V P N 7 Wi n d o w s NT V P N 7 VPN ( ) 7 Novell NetWare VPN 8.1 PPTP NT4 VPN Q 154091 M i c r o s o f t Windows NT RAS [ ] Windows NT4
/ / (FC 3)...
Modbus/TCP 1.0 1999 3 29 Andy Swales Schneider [email protected] ... 2 1.... 3 2.... 3 2.1.. 3 2.2..4 2.3..4 2.4... 5 3.... 5 3.1 0... 5 3.2 1... 5 3.3 2... 6 3.4 / /... 7 4.... 7 5.... 8 5.1 0... 9
2015年廉政公署民意調查
報 告 摘 要 2015 年 廉 政 公 署 周 年 民 意 調 查 背 景 1.1 為 了 掌 握 香 港 市 民 對 貪 污 問 題 和 廉 政 公 署 工 作 的 看 法, 廉 政 公 署 在 1992 至 2009 年 期 間, 每 年 均 透 過 電 話 訪 問 進 行 公 眾 民 意 調 查 為 更 深 入 了 解 公 眾 對 貪 污 問 題 的 看 法 及 關 注, 以 制 訂 適 切
VoIP Make a Rtp Call VoIP Abstract... 2 VoIP RTP...3 Socket IP...9 Config Two Voice-hub
VoIP... 2... 2 Abstract... 2... 3... 3 RTP...3 Socket...4...6...7 IP...9 Config Two Voice-hub... 10 1 12 VoIP VoIP voice-hub voice-hub Abstract At the beginning of this paper, we introducted the essential
CC213
: (Ken-Yi Lee), E-mail: [email protected] 49 [P.51] C/C++ [P.52] [P.53] [P.55] (int) [P.57] (float/double) [P.58] printf scanf [P.59] [P.61] ( / ) [P.62] (char) [P.65] : +-*/% [P.67] : = [P.68] : ,
ESP-Jumpstart
2016-2019 2019 08 08 Contents 1 3 1.1 ESP32.............................. 3 1.2.................................................. 5 2 7 2.1............................................. 7 2.2 ESP-IDF............................................
IP505SM_manual_cn.doc
IP505SM 1 Introduction 1...4...4...4...5 LAN...5...5...6...6...7 LED...7...7 2...9...9...9 3...11...11...12...12...12...14...18 LAN...19 DHCP...20...21 4 PC...22...22 Windows...22 TCP/IP -...22 TCP/IP
Microsoft Word - Entry-Level Occupational Competencies for TCM in Canada200910_ch _2_.doc
草 稿 致 省 級 管 理 單 位 之 推 薦 書 二 零 零 九 年 十 月 十 七 日 加 拿 大 中 醫 管 理 局 聯 盟 All rights reserved 序 言 加 拿 大 中 醫 管 理 局 聯 盟, 於 二 零 零 八 年 一 月 至 二 零 零 九 年 十 月 間, 擬 定 傳 統 中 醫 執 業 之 基 礎 文 件 由 臨 床 經 驗 豐 富 之 中 醫 師 教 育 者 及
1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un
Linux C July 27, 2016 Contents 1 Linux IDE 1 2 GCC 3 2.1 hello.c hello.exe........................... 5 2.2............................... 9 2.2.1 -Wall................................ 9 2.2.2 -E..................................
int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;
Memory & Pointer [email protected] 2.1 2.1.1 1 int *p int a 0x00C7 0x00C7 0x00C7 2.1.2 2 int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++; 2.1.3 1. 2. 3. 3 int A,
AL-M200 Series
NPD4754-00 TC ( ) Windows 7 1. [Start ( )] [Control Panel ()] [Network and Internet ( )] 2. [Network and Sharing Center ( )] 3. [Change adapter settings ( )] 4. 3 Windows XP 1. [Start ( )] [Control Panel
2005 3
Text 2009.4 [email protected] 2005 3 2.8M 1/4 20M / 500~600/sec 23 PC (1U*15/2U*8) 12 38G memcached 1U (frodo) AMD Athlon 64 1.8GHz 1G 160G SATA*2 Gentoo Linux MySQL 5 Quixote (a Python web framework)
網路安全:理論與實務 第二版
第 10 章 :Wireshark 封 包 分 析 軟 體 10-1 Wireshark 簡 介 10-2 Wireshark 的 安 裝 方 法 10-3 Wireshark 的 使 用 Wireshark 簡 介 - 發 展 歷 史 Wireshark (http://www.wireshark.org/) 是 一 個 開 放 原 始 碼 (open source software) 軟 體,
第一章 概论
1 2 3 4 5 6 7 8 Linux 7.1 7.1.1 1 1 2 3 2 3 1 2 3 3 1 2 3 7.1.2 1 2 1 2 3 4 5 7.1.3 1 1 2 3 2 7.1 3 7.1.4 1 1 PCB 2 3 2 PCB PCB PCB PCB PCB 4 1 2 PSW 3 CPU CPU 4 PCB PCB CPU PCB PCB PCB PCB PCB PCB PCB
像 客 样 使 命令行 徐 东
像 客 样 使 命令行 徐 东 1 1.1................................ 1 1.2................................. 3 1.3............................. 4 1.3.1 Linux............................ 5 1.3.2 macos............................
Java 1 Java String Date
JAVA SCJP Java 1 Java String Date 1Java 01 Java Java 1995 Java Java 21 Java Java 5 1-1 Java Java 1990 12 Patrick Naughton C++ C (Application Programming Interface API Library) Patrick Naughton NeXT Stealth
, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1
21 , 7, Windows,,,, : 010-62782989 13501256678 13801310933,,,, ;,, ( CIP) /,,. : ;, 2005. 11 ( 21 ) ISBN 7-81082 - 634-4... - : -. TP316-44 CIP ( 2005) 123583 : : : : 100084 : 010-62776969 : 100044 : 010-51686414
VIDEOJET connect 7000 VJC-7000-90 zh- CHS Operation Manual VIDEOJET connect 7000 zh-chs 3 目 录 1 浏 览 器 连 接 7 1.1 系 统 要 求 7 1.2 建 立 连 接 7 1.2.1 摄 像 机 中 的 密 码 保 护 7 1.3 受 保 护 的 网 络 7 2 系 统 概 述 8 2.1 实 况
EJB-Programming-4-cn.doc
EJB (4) : (Entity Bean Value Object ) JBuilder EJB 2.x CMP EJB Relationships JBuilder EJB Test Client EJB EJB Seminar CMP Entity Beans Session Bean J2EE Session Façade Design Pattern Session Bean Session
INTRODUCTION TO COM.DOC
How About COM & ActiveX Control With Visual C++ 6.0 Author: Curtis CHOU [email protected] This document can be freely release and distribute without modify. ACTIVEX CONTROLS... 3 ACTIVEX... 3 MFC ACTIVEX
Microsoft Word - PS2_linux_guide_cn.doc
Linux For $ONY PlayStatioin2 Unofficall General Guide Language: Simplified Chinese First Write By Beter Hans v0.1 Mail: [email protected] Version: 0.1 本 人 是 菜 鸟 + 小 白 欢 迎 指 正 错 误 之 处, 如 果 您 有 其 他 使 用 心 得
Microsoft Word - COC HKROO App I _Chi_ Jan2012.doc
附 錄 I 目 錄 項 目 貨 品 描 述 頁 數 (I) 活 動 物 ; 動 物 1 (II) 植 物 2 (III) 動 物 或 植 物 脂 肪 及 油 及 其 分 化 後 剩 餘 的 ; 經 處 理 可 食 的 脂 肪 ; 動 物 或 植 物 蠟 2 (IV) 經 配 製 的 食 品 ; 飲 料 酒 及 醋 ; 煙 草 及 製 成 的 煙 草 代 替 品 2 (V) 礦 產 5 (VI) 化
Microsoft PowerPoint - os_4.ppt
行 程 資 科 系 林 偉 川 行 程 概 念 行 程 與 程 式 主 要 的 不 同 點 : 程 式 是 被 放 在 外 部 的 儲 存 裝 置 如 磁 碟 上, 而 行 程 則 被 放 在 記 憶 體 中 程 式 在 儲 存 裝 置 中 是 靜 態 的, 而 行 程 在 記 憶 體 中 是 動 態 的, 它 會 隨 著 一 些 事 件 的 發 生 而 產 生 相 對 的 改 變 行 程, 就 是
Go构建日请求千亿微服务最佳实践的副本
Go 构建 请求千亿级微服务实践 项超 100+ 700 万 3000 亿 Goroutine & Channel Goroutine Channel Goroutine func gen() chan int { out := make(chan int) go func(){ for i:=0; i
Simulator By SunLingxi 2003
Simulator By SunLingxi [email protected] 2003 windows 2000 Tornado ping ping 1. Tornado Full Simulator...3 2....3 3. ping...6 4. Tornado Simulator BSP...6 5. VxWorks simpc...7 6. simulator...7 7. simulator
EK-STM32F
STMEVKIT-STM32F10xx8 软 件 开 发 入 门 指 南 目 录 1 EWARM 安 装... 1 1.1 第 一 步 : 在 线 注 册... 1 1.2 第 二 步 : 下 载 软 件... 2 1.3 第 三 步 : 安 装 EWARM... 3 2 基 于 STMEVKIT-STM32F10xx8 的 示 例 代 码 运 行... 6 2.1 GPIO Demo... 6 2.2
epub83-1
C++Builder 1 C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r 1.1 1.1.1 1-1 1. 1-1 1 2. 1-1 2 A c c e s s P a r a d o x Visual FoxPro 3. / C / S 2 C + + B u i l d e r / C
51 C 51 isp 10 C PCB C C C C KEIL
http://wwwispdowncom 51 C " + + " 51 AT89S51 In-System-Programming ISP 10 io 244 CPLD ATMEL PIC CPLD/FPGA ARM9 ISP http://wwwispdowncom/showoneproductasp?productid=15 51 C C C C C ispdown http://wwwispdowncom
经华名家讲堂
5.1 5.1.1 5.1.2 5.2 5.2.1 5.2.2 5.2.3 5.2.4 5.2.5 5.3 5.3.1 5.3.2 5.3.3 / 5.3.4 / 5.3.5 / 5.4 Internet 5.4.1 Internet 5.4.2 Intranet 1. 2. 1 31 5 5.1 5.1.1 Internet 1 Host 20 60 IBM 2000 2 20 60 20 60
-i-
-i- -ii- -iii- -iv- -v- -vi- -vii- -viii- -ix- -x- -xi- -xii- 1-1 1-2 1-3 1-4 1-5 1-6 1-7 1-8 1-9 1-10 1-11 1-12 1-13 1-14 1-15 1-16 1-17 1-18 1-19 1-20 1-21 2-1 2-2 2-3 2-4 2-5 2-6 2-7 2-8 2-9 2-10 2-11
Microsoft Word - 强迫性活动一览表.docx
1 1 - / 2 - / 3 - / 4 - / 5 - I. 1. / 2. / 3. 4. 5. 6. 7. 8. 9 10 11. 12. 2 13. 14. 15. 16. 17. 18. 19. 20 21. 22 23. 24. / / 25. 26. 27. 28. 29. 30. 31. II. 1. 2 3. 4 3 5. 6 7 8. 9 10 11 12 13 14. 15.
A API Application Programming Interface 见 应 用 程 序 编 程 接 口 ARP Address Resolution Protocol 地 址 解 析 协 议 为 IP 地 址 到 对 应 的 硬 件 地 址 之 间 提 供 动 态 映 射 阿 里 云 内
A API Application Programming Interface 见 应 用 程 序 编 程 接 口 ARP Address Resolution Protocol 地 址 解 析 协 议 为 IP 地 址 到 对 应 的 硬 件 地 址 之 间 提 供 动 态 映 射 阿 里 云 内 容 分 发 网 络 Alibaba Cloud Content Delivery Network 一
1 2 6 8 15 36 48 55 58 65 67 74 76 150 152 1 3 1 2 4 2 2001 2000 1999 12 31 12 31 12 31 304,347 322,932 231,047 14,018 16,154 5,665 (i) 0.162 0.193 0.082 (ii) 0.165 0.227 0.082 (iii) 10.08 13.37 6.47 0.688
6-1 Table Column Data Type Row Record 1. DBMS 2. DBMS MySQL Microsoft Access SQL Server Oracle 3. ODBC SQL 1. Structured Query Language 2. IBM
CHAPTER 6 SQL SQL SQL 6-1 Table Column Data Type Row Record 1. DBMS 2. DBMS MySQL Microsoft Access SQL Server Oracle 3. ODBC SQL 1. Structured Query Language 2. IBM 3. 1986 10 ANSI SQL ANSI X3. 135-1986
<D6D0B9FAB9C5CAB757512E6D7073>
黄 河 文 明 的 历 史 变 迁 丛 书 编 委 会 学 术 顾 问 李 学 勤 朱 绍 侯 姚 瀛 艇 郝 本 性 晁 福 林 王 巍 主 任 李 小 建 苗 长 虹 副 主 任 覃 成 林 高 有 鹏 牛 建 强 刘 东 勋 主 编 李 玉 洁 编 委 苗 书 梅 程 遂 营 王 蕴 智 张 新 斌 郑 慧 生 涂 白 奎 袁 俊 杰 薛 瑞 泽 陈 朝 云 孔 学 郑 贞 富 陈 彩 琴 石
Microsoft Word - 100118002.htm
100 年 度 11800 電 腦 軟 體 應 用 乙 級 技 術 士 技 能 檢 定 學 科 測 試 試 題 本 試 卷 有 選 擇 題 80 題, 每 題 1.25 分, 皆 為 單 選 選 擇 題, 測 試 時 間 為 100 分 鐘, 請 在 答 案 卡 上 作 答, 答 錯 不 倒 扣 ; 未 作 答 者, 不 予 計 分 准 考 證 號 碼 : 姓 名 : 選 擇 題 : 1. (3)
TCP/IP TCP/IP OSI IP TCP IP IP TCP/IP TCP/IP
TCP/IP : TCP/IP TCP/IP OSI IP TCP IP IP TCP/IP TCP/IP 1. ASCII EBCDIC Extended Binary-Coded Decimal Interchange Code 2. / (1) (2) Single System Image SSI) (3) I/O (4) 3.OSI OSI Open System Interconnection
SDS 1.3
Applied Biosystems 7300 Real-Time PCR System (With RQ Study) SDS 1.3 I. ~ I. 1. : Dell GX280 2.8GHz with Dell 17 Flat monitor 256 MB RAM 40 GB hard drive DVD-RW drive Microsoft Windows XP Operating System
对联故事
980.00 ... 1... 1... 2... 3... 3... 4... 4... 5... 5... 6... 7... 7... 8... 9...10...10...11...12...13...13...14...15...15...16...17 I II...18...18...19...19...20...21...21...22...22...23...24...25...25...26...26...27...28...29...29...30...30...31...32...32...33...34...34...35
(Methods) Client Server Microsoft Winsock Control VB 1 VB Microsoft Winsock Control 6.0 Microsoft Winsock Control 6.0 1(a). 2
(2005-01-26) (2005-01-26) (2005-02-27) PIC_SERVER (9) VB TCP/UDP Visual Basic Microsoft Winsock Control (MSWINSCK.OCX) UDP TCP Client Server Visual Basic UDP/TCP PIC_SERVER UDP/TCP 1. Microsoft Winsock
RDEC-RES
RDEC-RES-089-005 RDEC-RES-089-005 VI I II III 6 IV 7 3 V VI VII VIII IX X XI XII XIII XIV XV XVI XVII XVIII XIX XX 1 2 3 4 5 6 7 8 躰 ( 9 10 躰 11 12 躰 1 13 14 躰 15 16 躰 17 18 19 1 20 21 22 2 23 24 25 26
一个开放源码的嵌入式仿真环境 ― SkyEye
SkyEye SkyEye http://hpclab.cs.tsinghua.edu.cn/~skyeye/ I hear and I forget, I see and I remember, I do and I understand. SkyEye SkyEye SkyEye SkyEye SkyEye 1. SkyEye PC pervasive computing PC I O PDA
目 录
1 Quick51...1 1.1 SmartSOPC Quick51...1 1.2 Quick51...1 1.3 Quick51...2 2 Keil C51 Quick51...4 2.1 Keil C51...4 2.2 Keil C51...4 2.3 1 Keil C51...4 2.4 Flash Magic...9 2.5 ISP...9 2.6...10 2.7 Keil C51...12
AL-MX200 Series
PostScript Level3 Compatible NPD4760-00 TC Seiko Epson Corporation Seiko Epson Corporation ( ) Seiko Epson Corporation Seiko Epson Corporation Epson Seiko Epson Corporation Apple Bonjour ColorSync Macintosh
歡 迎 您 成 為 滙 豐 銀 聯 雙 幣 信 用 卡 持 卡 人 滙 豐 銀 聯 雙 幣 信 用 卡 同 時 兼 備 港 幣 及 人 民 幣 戶 口, 讓 您 的 中 港 消 費 均 可 以 當 地 貨 幣 結 算, 靈 活 方 便 此 外, 您 更 可 憑 卡 於 全 球 近 400 萬 家 特
歡 迎 您 成 為 滙 豐 銀 聯 雙 幣 信 用 卡 持 卡 人 滙 豐 銀 聯 雙 幣 信 用 卡 同 時 兼 備 港 幣 及 人 民 幣 戶 口, 讓 您 的 中 港 消 費 均 可 以 當 地 貨 幣 結 算, 靈 活 方 便 此 外, 您 更 可 憑 卡 於 全 球 近 400 萬 家 特 約 商 戶 簽 賬, 尊 享 種 種 購 物 飲 食 及 娛 樂 消 費 優 惠 如 需 查 詢 滙
A9RF716.tmp
1 PART I 1 2 3 4 5 6 7 8 Docker Docker Image Container Repository Docker le Docker Docker 8 1 Docker Linux 2 Docker Docker 3 5 Docker 6 Docker volume 7 8 Docker le Docker le 1 C H A P T E R 1 CPU Data
