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...