程序池實現

2021-08-22 19:20:30 字數 4320 閱讀 7861

本文是基於半同步/半非同步程序池的實現,半同步/半非同步模型主要是主程序監視listen套接字,然後發訊號給子程序,子程序完成鏈結和讀寫資料。

1.使用epoll實現i/0復用;

2.實現訊號和i/o事件的統一事件源。

3.使用管道進行子程序和父程序的通訊。

**如下:

#ifndef processpool_h

#define processpool_h

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*描述乙個子程序的類,m_pid是目標子程序的pid,m_pipefd是父程序和子程序通訊用的管道*/

class process

public:

pid_t m_pid;

int m_pipefd[2];

};/*程序池類,將它定義為模板類是為了**復用。其模板引數是處理邏輯任務的類*/

template< typename t >

class processpool

return m_instance;

}~processpool()

/*啟動程序池*/

void run();

private:

void setup_sig_pipe();

void run_parent();

void run_child();

private:

/*程序池允許的最大子程序數量*/

static const int max_process_number = 16;

/*每個子程序最多能處理的客戶數量*/

static const int user_per_process = 65536;

/*epoll最多能處理的事件數*/

static const int max_event_number = 10000;

/*程序池中的程序總數*/

int m_process_number;

/*子程序在池中的序號,從0開始*/

int m_idx;

/*每個程序都有乙個epoll核心時間,用m_epollfd標識*/

int m_epollfd;

/*監聽socket*/

int m_listenfd;

/*子程序通過m_stop來決定是否停止執行*/

int m_stop;

/*儲存所有子程序的描述資訊*/

process* m_sub_process;

/*程序池靜態例項*/

static processpool< t >* m_instance;

};template< typename t >

processpool< t >* processpool< t >::m_instance = null;

/*用於處理訊號的管道,以實現同意事件源。後面稱之為訊號管道*/

static int sig_pipefd[2];

static int setnonblocking( int fd )

static void addfd( int epollfd, int fd )

/*從epollfd標識的epoll核心時間表中刪除fd上的所有註冊事件*/

static void removefd( int epollfd, int fd )

/*訊號處理函式*/

static void sig_handler( int sig )

/*設定訊號處理函式*/

static void addsig( int sig, void( handler )(int), bool restart = true )

sigfillset( &sa.sa_mask );

assert( sigaction( sig, &sa, null ) != -1 );

}/*程序池建構函式。引數listenfd是監聽socket,它必須在建立程序池之前被建立,否則子程序無法直接引用它。

引數process_number指定程序池中子程序的數量*/

template< typename t >

processpool< t >::processpool( int listenfd, int process_number )

: m_listenfd( listenfd ), m_process_number( process_number ), m_idx( -1 ), m_stop( false )

else

}}/*統一事件源*/

template< typename t >

void processpool< t >::setup_sig_pipe()

/*父程序中m_idx值為-1,子程序m_idx值大於等於0,我們據此判斷接下來要執行的是父程序**還是子程序***/

template< typename t >

void processpool< t >::run()

run_parent();

}template< typename t >

void processpool< t >::run_child()

for ( int i = 0; i < number; i++ )

else

addfd( m_epollfd, connfd );

/*模板類t必須實現init方法,以初始化乙個客戶連線。我們直接使用connfd來索引邏輯處理物件(t型別的物件),

以提高程式效率*/

users[connfd].init( m_epollfd, connfd, client_address );}}

/*下面處理子程序接收到的訊號*/

else if( ( sockfd == sig_pipefd[0] ) && ( events[i].events & epollin ) )

else

break;

}case sigterm:

case sigint:

default:}}

}}

else if( events[i].events & epollin )

else}}

delete users;

users = null;

close( pipefd );

//close( m_listenfd );

及所謂的「物件由哪個函式建立,就應該由哪個函式銷毀」*/

close( m_epollfd );

}template< typename t >

void processpool< t >::run_parent()

for ( int i = 0; i < number; i++ )

i = (i+1)%m_process_number;

}while( i != sub_process_counter );

if( m_sub_process[i].m_pid == -1 )

sub_process_counter = (i+1)%m_process_number;

//send( m_sub_process[sub_process_counter++].m_pipefd[0], ( char* )&new_conn, sizeof( new_conn ), 0 );

send( m_sub_process[i].m_pipefd[0], ( char* )&new_conn, sizeof( new_conn ), 0 );

printf( "send request to child %d\n", i );

//sub_process_counter %= m_process_number;

}/*下面處理父程序接收到的訊號*/

else if( ( sockfd == sig_pipefd[0] ) && ( events[i].events & epollin ) )

else}}

m_stop = true;

for( int i = 0; i < m_process_number; ++i )

}break;

}case sigterm:

case sigint:

}break;

}default:}}

}}

else}}

//close( m_listenfd );

/*由建立者關閉上面這個檔案描述符*/

close( m_epollfd );

}#endif

如何實現程序池

有位站友問,如何在linux下實現程序池技術,原貼見 之前雖對程序池這個名詞早有耳聞,但一直沒有真正接觸過。乍一聽好像有點複雜,但稍微一想卻也簡單,下面我就按自己的想法來實現乙個簡單的模型。跟最簡單的資源管理一樣,程序池技術的應該致少由以下兩部分組成 資源程序 預先建立好的空閒程序,管理程序會把工作...

Linux 程序池實現

程序池在伺服器應用中有很多很多 下面是半同步半非同步程序池的實現 ifndef processpool h define processpool h include include include include include include include include include inc...

記憶體池 程序池 執行緒池介紹及執行緒池C 實現

平常我們使用new malloc在堆區申請一塊記憶體,但由於每次申請的記憶體大小不一樣就會產生很多記憶體碎片,造成不好管理與浪費的情況。記憶體池則是在真正使用記憶體之前,先申請分配一定數量的 大小相等 一般情況下 的記憶體塊留作備用。當有新的記憶體需求時,就從記憶體池中分出一部分記憶體塊,若記憶體塊...