Study notes about Poco::TCPServer framework (select model is used under windows).

WBOY
Release: 2016-08-08 09:27:42
Original
1155 people have browsed it

Instructions

Why am I writing this article? I have read Ah Er’s Dream Boat’s http://www.cppblog.com/richbirdandy/archive/2010/09/10/123994.html

Unfortunately, there are too many codes and it looks cumbersome. So I am going to simplify it with a flow chart for easy understanding. It is also convenient for myself to use in the future.

The content of this article is based on window api analysis.

The poco in this article is version 1.4.6p4 (2014-04-18). Although the poco version is now 1.6, the call has not changed much.

poco download address: http://pocoproject.org/releases/

This article uses TimeServer.cpp as the entry point for analysis:

Things to know before you start:

1,Inline inline function: Please refer to:

http://blog.sina.com.cn/s/blog_90e888f50100zgo2.html

Mainly to improve execution efficiency.

2, Overloading, rewriting, hiding of class member functions,

Reference:

dazhong159's

http://blog.csdn.net/dazhong159/article/details/7844369

3, Principle of select model:

Quote

A humorous explanation of the six Socket I/O models

http://blog.csdn.net/normalnotebook/article/details/999840

Content:

for i:=0 to fd_read.fd_count-1 do //Note, fd_count

It is a synchronous operation.

Lao Chen really wants to see his daughter’s letter. So much so that he goes downstairs to check the mailbox every 10 minutes to see if there is a letter from his daughter~~~~~
In this case, "going downstairs to check the mailbox" and then going back upstairs took up so much time that Chen couldn't do other work.
The select model is very similar to Lao Chen’s situation: check over and over again...if there is data...receive/send...

<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>
Copy after login

So, the select model can only be used for general small connections....High concurrency is not acceptable.

4,

Understanding of constructor initialization sequence

C++ constructors are called in the following order:
(1) The constructors of any virtual base class are constructed in the order in which they are inherited;
(2) The constructors of any non-virtual base class are constructed in the order in which they are inherited;
(3) The constructors of any member objects are called in the order in which they are declared;
(4) The class's own constructor.

5, About FastMutex mutex variables

bool NotificationQueue::empty() const
{
FastMutex::ScopedLock lock(_mutex);
return _nfQueue.empty();
}

After empty() is executed, call the ~FastMutex::ScopedLock destructor to release it.

The critical section used under window:

class Foundation_API MutexImpl
{
protected:
MutexImpl();
~MutexImpl();
void lockImpl();
bool tryLockImpl();
bool tryLockImpl(long milliseconds);
void unlockImpl();

private:
CRITICAL_SECTION _cs;//Critical section
};

6, About thread:

Use under window

_thread = (HANDLE) _beginthreadex(NULL, _stackSize, ent, this, 0, &threadId);

Execute thread operations.

7. Waiting for events and synchronization of connection requests are used

WaitForSingleObject(This is also my favorite)

Activate reset through SetEvent (),ResetEvent().

8, static_cast<> reinterpret_cast<> dynamic_cast<> usage.

Please refer to:

http://www.cnblogs.com/bastard/archive/2011/12/14/2288117.html

http://www.cnblogs.com/jerry19880126/archive/2012/08/14/2638192.html

Like in code:

void* pThread;

reinterpret_cast(pThread)->_pRunnableTarget->run();

//reinterpret_cas This conversion is the most "unsafe". Conversion between two unrelated class pointers can be achieved using this conversion. For example

_threadId = static_cast(threadId);

//static_cast is used for basic data type conversion (char, int) and conversion between pointers

9, About the smart (smart) pointer auto_ptr.

auto_ptr To put it simply, it ensures that the created resources can be freed when exiting (regardless of whether there is an exception or not)

std::auto_ptr pConnection(_pConnectionFactory->createConnection(pCNf->socket()));

AutoPtr pNf = _queue.waitDequeueNotification(idleTime);

Can be found directly in

template
class auto_ptr
{ // wrap an object pointer to ensure destruction

You can refer to:

More Effective C++ Chinese version.pdf 7.4 Item M28: Smart Pointer Chapter (find and download on baidu)

http://blog.chinaunix.net/uid-9525959-id-2001803.html

Snippets from

:

如何避免使用auto_ptr的缺陷
    auto_ptr并不是完美无缺的,它的确很方便,但也有缺陷,在使用时要注意避免。首先,不要将auto_ptr对象作为STL容器的元素。C++标准明确禁止这样做,否则可能会碰到不可预见的结果。
    auto_ptr的另一个缺陷是将数组作为auto_ptr的参数:  
auto_ptr  pstr (new char[12] ); //数组;为定义
 
    记住不管什么时候使用数组的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>
Copy after login

增加线程池中线程数(费话!),来加快select 中处理.

个人愚见,可能有些没写明白.还望高手指点.

谢谢.

以上就介绍了关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记.,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template