Beschreibung
Warum schreibe ich diesen Artikel? Ich habe Ah Er’s Dream Boats
Leider gibt es zu viele Codes und es sieht umständlich aus. Deshalb habe ich ein Flussdiagramm erstellt, um es einfacher zu verstehen und für die zukünftige Verwendung zu vereinfachen Der Inhalt dieses Artikels basiert auf der Fenster-API-Analyse.
Der Poco dieses Artikels ist Version 1.4.6p4 (18.04.2014)Obwohl die Poco-Version jetzt 1.6 ist, hat sich am Aufruf nicht viel geändert.
Poco-Download-Adresse: http://pocoproject.org/releases/
Dieser Artikel verwendet TimeServer.cpp als Einstiegspunkt für die Analyse:
Wissenswertes, bevor Sie beginnen:
1, Inline-Inline-Funktion: Sie können sich auf Folgendes beziehen:http://blog.sina.com.cn/s/blog_90e888f50100zgo2.html
Hauptsächlich zur Verbesserung der Ausführungseffizienz.
2, Überladen, Umschreiben, Ausblenden von Klassenmitgliedsfunktionen,
Referenz:
dazhong159's
http://blog.csdn.net/dazhong159/article/details/7844369
3, Prinzip der Modellauswahl:
Zitat
Eine humorvolle Erklärung der sechs Socket-I/O-Modelle
http://blog.csdn.net/normalnotebook/article/details/999840
Inhalt von
:
for i:=0 to fd_read.fd_count-1 do //Note, fd_count Es handelt sich um einen synchronen Vorgang.
Der alte Chen möchte unbedingt den Brief seiner Tochter sehen. So sehr, dass er alle 10 Minuten nach unten geht, um den Briefkasten zu überprüfen, um zu sehen, ob ein Brief von seiner Tochter da ist~~~~~In diesem Fall hielt Chen so sehr davon ab, „nach unten zu gehen, um den Briefkasten zu überprüfen“ und dann wieder nach oben zu gehen, dass er nicht in der Lage war, anderen Arbeiten nachzugehen.
Das ausgewählte Modell ist der Situation von Lao Chen sehr ähnlich: immer wieder prüfen...ob Daten vorhanden sind...empfangen/senden...
Das Select-Modell kann also nur für allgemeine kleine Verbindungen verwendet werden. Eine hohe Parallelität ist nicht möglich.
<span>..... MainSock :</span>=<span> socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); addr.sin_family :</span>=<span> AF_INET; addr.sin_port :</span>= htons(<span>5678</span><span>); addr.sin_addr.S_addr :</span>=<span> htonl(INADDR_ANY); bind( MainSock, @addr, </span><span>sizeof</span><span>(addr) ); listen( MainSock, </span><span>5</span><span> ); </span><span>while</span> (not Terminated) <span>do</span><span> begin FD_ZERO( fd_read ); FD_SET( MainSock, fd_read ); timeout.tv_sec :</span>= <span>0</span><span>; timeout.tv_usec :</span>= <span>500</span><span>; </span><span>if</span> <span>select</span>( <span>0</span>, @fd_read, nil, nil, @timeout ) > <span>0</span> then <span>//</span><span>至少有1个等待Accept的connection</span> <span> begin </span><span>if</span><span> FD_ISSET( MainSock, fd_read ) then begin </span><span>for</span> i:=<span>0</span> to fd_read.fd_count-<span>1</span> <span>do</span> <span>//</span><span>注意,fd_count <= 64,也就是说select只能同时管理最多64个连接</span> <span> begin len :</span>= <span>sizeof</span><span>(addr); ASock :</span>=<span> accept( MainSock, addr, len ); </span><span>if</span> ASock <><span> INVALID_SOCKET then ....</span><span>//</span><span>为ASock创建一个新的线程,在新的线程中再不停地select</span> <span> end; end; end; end; </span><span>//</span><span>while (not self.Terminated)</span> <span> shutdown( MainSock, SD_BOTH ); closesocket( MainSock ); end;<br></span></span>
Verständnis der Konstruktor-Initialisierungssequenz
C-Konstruktoren werden in der folgenden Reihenfolge aufgerufen:
(1) Die Konstruktoren jeder virtuellen Basisklasse werden in der Reihenfolge erstellt, in der sie vererbt werden
(2) Die Konstruktoren jeder nicht-virtuellen Basisklasse werden in der Reihenfolge erstellt, in der sie vererbt werden (3) Die Konstruktoren aller Mitgliedsobjekte werden in der Reihenfolge aufgerufen, in der sie deklariert werden (4) Der klasseneigene Konstruktor.
5, Über FastMutex-Mutex-Variablen
bool NotificationQueue::empty() const
{
return _nfQueue.empty();
}
Nachdem empty() ausgeführt wurde, rufen Sie den Destruktor ~FastMutex::ScopedLock auf, um ihn freizugeben.
Der kritische Abschnitt, der unter Fenster verwendet wird:
{
protected:MutexImpl();
~MutexImpl(); void lockImpl();
bool tryLockImpl();
bool tryLockImpl(long milliseconds);
void unlockImpl();
private:
CRITICAL_SECTION _cs;//Kritischer Abschnitt
};
6, Über Threads:
Unter Fenster verwenden
Thread-Operationen ausführen.
7, Warten auf Ereignisse, Synchronisierung von Verbindungsanfragen wird verwendet
WaitForSingleObject (das ist auch mein Favorit)
Reset durch SetEvent (),ResetEvent() aktivieren.
8, static_cast<> reinterpret_cast<> dynamic_cast<>
Bitte beachten Sie:
http://www.cnblogs.com/bastard/archive/2011/12/14/2288117.html
http://www.cnblogs.com/jerry19880126/archive/2012/08/14/2638192.html
Wie im Code:
void* pThread;
reinterpret_cast
//reinterpret_cas Diese Konvertierung ist die „unsicherste“, die mit dieser Konvertierung zwischen zwei unabhängigen Klassenzeigern erreicht werden kann
_threadId = static_cast//static_cast wird für die grundlegende Datentypkonvertierung (char, int) und die Konvertierung zwischen Zeigern verwendet
9, Über den intelligenten (intelligenten) Zeiger auto_ptr.
auto_ptr Vereinfacht gesagt stellt es sicher, dass die erstellten Ressourcen beim Beenden freigegeben werden können (unabhängig davon, ob eine Ausnahme vorliegt oder nicht)
std::auto_ptr
AutoPtr
kann direkt im
class auto_ptr
{ // Einen Objektzeiger umschließen, um die Zerstörung sicherzustellenSie können sich beziehen auf:
Effektivere chinesische C-Version.pdf 7.4 Punkt M28: Smart Pointer-Kapitel (auf Baidu finden und herunterladen)
http://blog.chinaunix.net/uid-9525959-id-2001803.html
Fragment aus
如何避免使用auto_ptr的缺陷
auto_ptr并不是完美无缺的,它的确很方便,但也有缺陷,在使用时要注意避免。首先,不要将auto_ptr对象作为STL容器的元素。C++标准明确禁止这样做,否则可能会碰到不可预见的结果。
auto_ptr的另一个缺陷是将数组作为auto_ptr的参数:
auto_ptr
记住不管什么时候使用数组的new操作时,必须要用delete[]来摧毁数组。因为auto_ptr的析构函数只对非数组类型起作用。所以数组是不能被正确摧毁的话,程序的行为是不明确的。总之,auto_ptr控制一个由new分配的单对象指针,仅此而已。
不过C++ 11标准中解决了这问题:
unique_ptr
smart pointer with unique object ownership semantics
只能有一个主人的指针,可以用于STL容器
shared_ptr
smart pointer with shared object ownership semantics
可共享的指针
weak_ptr
weak reference to an object managed by std::shared_ptr
弱引用指针
auto_ptr
smart pointer with strict object ownership semantics
只能有一个主人的指针,不能用于STL容器
走远了,想深入(不要想多了-_- ),请baidu...
看完上面之些,发现是不是觉得 各种知识又巩固了.
所以还是要看开源代码,之前公司整死不用开源的...哎...
开始
代码中主要使用类的关系
图片过宽,不能显示(请 在新标签中打开图片.谢谢.)
主要的几个类:
1,TCPServer 主服务,负责 调用select 模型,来处理 连接消息的变化.
2,PooledThread 是线程池.当被激活时,调用 TCPServerDispatcher::run() 来处理收到包后的具体请求.而 TCPServerDispatcher::run() 中调用
TimeServerConnection.run(). TimeServerConnection.run()通过子类隐藏 来实现 程序员 自定义 功能. 不得不说写POCO的大牛利害.
3,TCPServerDispatcher,派遣管理者(先这么叫吧). 接收消息变化,放入队列.管理 连接数.
当放入队列时,会激活 PooledThread 中的事件 .
PooledThread 又反过来 激活 TCPServerDispatcher::run() [姑且叫 有条件时相互激活吧 ]
4,TCPServerConnection.实现具体行为,通过继承由子类的 run() 来自定义实现 功能.
5,TCPServerConnectionFactory 负责创建和管理 TCPServerConnection.
6,TCPServerParams 这个参数管理 ,就不说了.你懂的.
看完主要几个类的介绍,其它流程都应该懂大概了.
流程图:
由于图太长的关系多,
图片过宽,不能显示(请 在新标签中打开图片.谢谢.)
先看看 PooledThread 的流程吧
再看下TCPServer 主宰的流程
图片过宽,不能显示(请 在新标签中打开图片.谢谢.)
先到这儿,还没有写完.
我们可以改变什么:
ThreadPool(<span>int</span> minCapacity = <span>2</span><span>, </span><span>int</span> maxCapacity = <span>16</span><span>, </span><span>int</span> idleTime = <span>60</span><span>, </span><span>int</span> stackSize =<span> POCO_THREAD_STACK_SIZE); </span><span>///</span><span> Creates a thread pool with minCapacity threads. </span><span>///</span><span> If required, up to maxCapacity threads are created </span><span>///</span><span> a NoThreadAvailableException exception is thrown. </span><span>///</span><span> If a thread is running idle for more than idleTime seconds, </span><span>///</span><span> and more than minCapacity threads are running, the thread </span><span>///</span><span> is killed. Threads are created with given stack size.</span>
增加线程池中线程数(费话!),来加快select 中处理.
个人愚见,可能有些没写明白.还望高手指点.
谢谢.
以上就介绍了关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记.,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。