簡 易 版 的 進 程 池 模 型 學 習

2021-09-30 14:33:49 字數 3890 閱讀 2280

1、程序池流程

父程序流程

第一步:

make_child 初始化子程序

迴圈建立子程序,並初始化父程序的子程序管理結構體陣列 child, 通過 socket_pair 將 socket

描述符一端放入陣列

子程序流程

recv_fd 等待父程序傳送任務

send_file 傳送檔案資料

write 向父程序傳送完成任務

第二步:

父程序 epoll 監控 fd_listen 描述符。

父程序 epoll 監控 parr 結構體陣列的 socket 描述符

第三步:

while 1 啟動 epoll_wait, 等待是否有客戶端連線

有客戶端連線後, accept 獲得描述符, 迴圈找到非忙碌的子程序, 並傳送給子程序, 標記對

應子程序忙碌。

當子程序完成任務後, 父程序一旦監控 socket 描述符可讀, 代表子程序非忙碌, 然後標記子

程序非忙碌。

2、標頭檔案及相關資料結構

#include#include #include#include #include #include #include #include #include #include #include #include #include #include #include #include #include#define filename "file"

typedef structchild,*pchild;

typedef structtrain,*ptrain;

void send_fd(int fdw,int fd);

void recv_fd(int fdr,int* fd);

void make_child(pchild p,int len);

void child_handle(int fdr);

void send_data(int );

int send_n(int ,char *,int);

int recv_n(int,char *,int);

3、父程序源**

#include"func.h"

int exitfds[2]; //退出拉起管道

int exit_num=0; //用於退出時判斷機制

void set_status(int fd)

void sighandle(int signum)

int main(int argc,char **ar**)

int child_len=atoi(ar**[3]);

//首先為每個子程序動態申請空間,用指標實現陣列效果

pchild p=(pchild)calloc(child_len,sizeof(child));

//建立子程序,並初始化資料結構,//封裝成乙個init函式

make_child(p,child_len);

int sfd;

sfd=socket(af_inet,sock_stream,0);

if(sfd==-1)

struct sockaddr_in ser;

ser.sin_addr.s_addr=inet_addr(ar**[1]);

ser.sin_port=htons(atoi(ar**[2]));

ser.sin_family=af_inet;

int ret;

ret=bind(sfd,(struct sockaddr *)&ser,sizeof(ser));

if(-1==ret)

int epfd=epoll_create(1); //創造乙個epfd的控制代碼

struct epoll_event event,*evs;

evs=(struct epoll_event *)calloc(child_len+1,sizeof(struct epoll_event));

memset(&event,0,sizeof(event));

event.data.fd=sfd;

event.events=epollin;

epoll_ctl(epfd,epoll_ctl_add,sfd,&event);

int i;

for(i=0;i0)

;strcpy(flag,"over");

while(1)

}void make_child(pchild p,int len)

}void recv_fd(int fdr,int* fd)

*fd=*(int*)cmsg_data(cmsg);

}

6、子程序的主要邏輯業務----傳送檔案

#include"func.h"

void send_data(int newfd)

int fd=open(filename,o_rdonly);

if(-1==fd)

struct stat filestat;

fstat(fd,&filestat);

t.len=sizeof(long);

memcpy(t.buf,&filestat.st_size,sizeof(filestat.st_size));

send_n(newfd,(char*)&t,4+t.len);

while(memset(t.buf,0,sizeof(t.buf)),(t.len=read(fd,t.buf,sizeof(t.buf)))>0)

t.len=0;

send_n(newfd,(char *)&t,4+t.len);

close(newfd);

close(fd);

}

7、為了匹配網路兩端的傳送速度,以及傳送大檔案時,可能的緩衝區大小的瓶頸,造成

的資料丟失,故需要精確控制要傳送和接受的位元組數,需要迴圈傳送。

#include"func.h"

int send_n(int sfd,char *p,int len)

child,*pchild;

void send_fd(int fdw,int fd);

void recv_fd(int fdr,int* fd);

void make_child(pchild p,int len);

void child_handle(int fdr);

int recv_n(int,char *,int);

int send_n(int sfd,char *p,int len)

}else

}close(fd);

close(sfd);

return 0;

}

簡易版的Tween

與之前的tween 類似,只是這個為簡潔版 動畫處理器 緩動效果 param obj dom物件 param prop 要改變的樣式屬性,如left 填opacity時,1表示不透明,0表示完全透明 param v1 初始值 不帶px param v2 終止值 不帶px param opt obje...

簡易版celery的實現

最近學習了下,celery原始碼,看了一點點皮毛後,自己動手寫了個簡易的celery,通過redis作為broker,沒有複雜的路由匹配規則,佇列和任務之間乙個直接匹配的簡易規則。這裡對專案簡單的記錄下。是celery類所在位置,具體實現了celery的啟動,載入配置檔案,任務裝飾器 utils 下...

最少操作次數的簡易版

給定兩個字串,僅由小寫字母組成,它們包含了相同字元。求把第乙個字串變成第二個字串的最小操作次數,且每次操作只能對第乙個字串中的某個字元移動到此字串中的開頭。例如給定兩個字串 abcd bcad 輸出 2,因為需要操作2次才能把 abcd 變成 bcad 方法是 abcd cabd bcad。incl...