swoole流程圖

程圖,便於之後回憶下react

 

 

總結幾點以下:緩存

首先主進程監聽pipe_master事件,swoole

子進程監聽pipe_worker事件異步

 

經過主進程派生的線程 tcp

swReactorThread *thread = swServer_get_thread(serv, reactor_id);oop

swReactor *reactor = &thread->reactor;spa

 

reactor主要監聽的句柄有accept的new_fd,以及主進程的pipe_master管道fd.net

reactor->setHandle(reactor, SW_FD_CLOSE, swReactorThread_onClose);
reactor->setHandle(reactor, SW_FD_UDP, swReactorThread_onPackage);
/**
 * receive data from worker process pipe
 */
reactor->setHandle(reactor, SW_FD_PIPE, swReactorThread_onPipeReceive);


當子進程處理完數據要發送給客戶端的時候,就會往pipe_worker寫數據,此時會觸發pipe_master的讀操做線程

將獲取的數據直接發送給客戶端,若是寫入失敗,就會將數據寫入到conn->out_buffer中進行緩存,而且會add
if (reactor->set(reactor, fd, SW_EVENT_TCP | SW_EVENT_WRITE | SW_EVENT_READ) < 0
            && (errno == EBADF || errno == ENOENT))
add的這個事件意味着會觸發下面所介紹的
/**
 * [ReactorThread] worker pipe can write.
 */
reactor->setHandle(reactor, SW_FD_PIPE | SW_EVENT_WRITE, swReactorThread_onPipeWrite);
thread->reactor.add(&thread->reactor, pipe_fd, SW_FD_PIPE | SW_EVENT_WRITE);
其中//上面介紹的swReactorThread_onPipeReceive寫入失敗後會觸發 reactor->setHandle(reactor, SW_FD_TCP | SW_EVENT_WRITE, swReactorThread_onWrite); 

    //tcp receive設計

//Thread mode must copy the data.
    //will free after onFinish
    if (serv->open_eof_check)
    {
將數據緩存在conn->in_buffer字段中

        reactor->setHandle(reactor, SW_FD_TCP, swReactorThread_onReceive_buffer_check_eof);
    }
    else if (serv->open_length_check)
    {
數據緩存在conn->object字段中

        reactor->setHandle(reactor, SW_FD_TCP, swReactorThread_onReceive_buffer_check_length);
    }
    else if (serv->open_http_protocol)
    {
數據緩存在conn->object字段中

        reactor->setHandle(reactor, SW_FD_TCP, swReactorThread_onReceive_http_request);
    }
    else
    {
        reactor->setHandle(reactor, SW_FD_TCP, swReactorThread_onReceive_no_buffer);
    }
第一個觸發點就是當主進程
ret = serv->reactor_threads[reactor_id].reactor.add(&(serv->reactor_threads[reactor_id].reactor), new_fd,
				SW_FD_TCP | SW_EVENT_READ);

 

swReactorThread_onReceive_http_request等而後介紹子進程的pipe_worker
SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE);
/**
 * receive data from reactor
 */
SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive);


主進程accept數據後就寫入pipe_master從而觸發子進程的

SW_EVENT_PACKAGE_END

/**
 * pipe can write.
 */

SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_EVENT_WRITE, swWorker_onPipeWrite);

而後添加句柄SwooleG.main_reactor->add(SwooleG.main_reactor, pipefd, SW_FD_PIPE | SW_EVENT_WRITE);
其中swoole有ontask的執行任務功能,在我看來和上述的子進程模式同樣,只不過單獨開闢了一堆子進程來處理所謂你須要執行「任務」功能而設計,在我看來事相同實現方式處理不一樣需求
factory->notify(&serv->factory, &notify_ev);
上面介紹了不少將數據緩存的位置好比conn->in_buffer, conn->object, thread->buffer_pipe, p->worker_buffer,其中前兩個你們須要注意的是conn是具體某個鏈接,而且是對外的,由於因爲外界鏈接咱們沒法預計,因此用了異步模型,爲了區分每一個鏈接過來的數據就必須用惟一的conn來關聯,後兩組是每組進程一個緩存池,由於後兩組是管道通訊,在咱們完整拿到了某個conn的數據,以及完整的要發送client完整數據,對咱們來講是可控的,因此就能夠一會兒發送出去,保證這批發送時同一個鏈接的數據,不會有不一樣鏈接數據交叉的狀況,因此就要求咱們管道之間通訊必須保證是同一個鏈接的完整數據,不然緩衝區就亂了,這也是爲何數據包能夠分爲start,和end的緣由,由於必定發過來是同一個鏈接數據
, 
read(event->fd, &task, sizeof(task)
這樣寫應該是有考慮吧,我是百思不得其解,不知道誰能解答一下
 
核心四個文件Server.c FactoryProcess.c Worker.c RectorThread.c
factory->object = object;
factory->dispatch = swFactoryProcess_dispatch;
/**
factory->finish = swFactoryProcess_finish;
可是主進程是從新賦值的,這點須要注意
//主進程須要設置爲直寫模式
factory->finish = swFactory_finish;其中關閉鏈接在此實現
 
/**
 * worker main loop
 */
SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE);        
SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive);
//write事件爲了write失敗發送緩衝區而創建的事件p->worker_buffer
SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_EVENT_WRITE, swWorker_onPipeWrite);
/**
 * proxy模式
 * 在單獨的n個線程中接受維持TCP鏈接
 */
reactor->setHandle(reactor, SW_FD_CLOSE, swReactorThread_onClose);
reactor->setHandle(reactor, SW_FD_UDP, swReactorThread_onPackage);
//線程接受work輸出給client的內容
reactor->setHandle(reactor, SW_FD_PIPE, swReactorThread_onPipeReceive);
reactor->setHandle(reactor, SW_FD_PIPE | SW_EVENT_WRITE, swReactorThread_onPipeWrite);
//write事件爲了write失敗發送緩衝區而創建的事件conn_buffer
reactor->setHandle(reactor, SW_FD_TCP | SW_EVENT_WRITE, swReactorThread_onWrite);
//下面是線程接受accept的fd套接字
reactor->setHandle(reactor, SW_FD_TCP, swReactorThread_onReceive_buffer_check_eof);
reactor->setHandle(reactor, SW_FD_TCP, swReactorThread_onReceive_buffer_check_length);
reactor->setHandle(reactor, SW_FD_TCP, swReactorThread_onReceive_http_request);
reactor->setHandle(reactor, SW_FD_TCP, swReactorThread_onReceive_no_buffer);
http://blog.csdn.net/xiaolei1982/article/details/41853583
相關文章
相關標籤/搜索