php多线程(win系统无法启动)

  1 !defined('QY_JK_API_ROOT') && die('VOID');
2
3 declare(ticks=1);
4 class thread{
5 public $MaxTask = 5; //最大任务包数
6 public $TaskPackag = array(); //任务包列表
7 public $CurrentPackId = 0; //当前任务包Id
8 public $MaxProcesses = 25; //最大线程数
9 public $CurrentList = array(); //当前处理的线程
10 public $SignalList = array(); //当前处理的线程信号
11 public $TaskList = array(); //任务列表
12 public $MaxRetryNum = 3; //重试发送最大次数
13
14 public function __construct()
15 {
16 pcntl_signal(SIGCHLD, array($this, "ChildSgHand"));
17 }
18
19 //子线程信号句柄
20 public function ChildSgHand($Signo, $Pid=null, $Status=null)
21 {
22 if(!$Pid)
23 {
24 $Pid = pcntl_waitpid(-1, $Status, WNOHANG);
25 }
26 //检测子进程是否退出
27 while($Pid > 0)
28 {
29 if($Pid && isset($this -> CurrentList[$Pid]))
30 {
31 $ExitCode = pcntl_wexitstatus($Status);
32 if($ExitCode == 0)
33 {
34 //执行完成
35 unset($this -> CurrentList[$Pid]);
36 $this -> ExecRun();
37 }
38 }else if($Pid){
39 //添加队列
40 $this -> SignalList[$Pid] = $Status;
41 }
42 $Pid = pcntl_waitpid(-1, $Status, WNOHANG);
43 }
44 return true;
45 }
46
47 //是否可以fork
48 public function IsFork()
49 {
50 $Return = false;
51 $CurrentNum = count($this -> CurrentList);
52 if($CurrentNum < $this -> MaxProcesses) $Return = true;
53 return $Return;
54 }
55
56 //启动线程任务
57 public function ExecRun()
58 {
59 if(count($this -> TaskList) < 1) return true;
60 while($this -> IsFork()){
61 $TaskKey = key($this -> TaskList);
62 $TaskVal = $this -> TaskList[$TaskKey];
63 unset($this -> TaskList[$TaskKey]);
64 $this -> ToFork($TaskVal, $this -> CurrentPackId);
65 if(count($this -> TaskList) < 1) break;
66 }
67 }
68
69 //是否可以读取任务包
70 public function IsReadTask()
71 {
72 $Return = false;
73 $TaskPackagNum = count($this -> TaskPackag);
74 if($TaskPackagNum < $this -> MaxTask) $Return = $this -> MaxTask - $TaskPackagNum;
75 return $Return;
76 }
77
78 //读取任务包
79 public function ReadTask()
80 {
81 if($Size = $this -> IsReadTask())
82 {
83 //载入任务包
84 $TaskPack = $this -> MysqlReadTaskPack($Size);
85 if(IsType($TaskPack, 'array'))
86 {
87 $DBLink = false;
88 foreach($TaskPack as $Key => $Val)
89 {
90 if(!isset($this -> TaskPackag[$Val['tl_sysid']]))
91 {
92 if(!$this -> IsReadTask()) break;
93 if(!$DBLink) $DBLink = MysqlGetLink();
94 if(!$DBLink) break;
95 $sql = 'update '.MysqlGetTab('task_list').' set tl_state=2 where tl_sysid=\''.$Val['tl_sysid'].'\' and tl_state=0';
96 if(!mysql_query($sql, $DBLink)) break;
97 $this -> TaskPackag[$Val['tl_sysid']] = $Val;
98 }
99 }
100 if($DBLink) mysql_close($DBLink);
101 }
102 }
103 return true;
104 }
105
106 //开始任务
107 public function Start()
108 {
109 $this -> ReadTask();
110 $this -> LoadTask();
111 $this -> ExecRun();
112 $this -> Result();
113 }
114
115 //是否结束进程
116 public function IsExit()
117 {
118 return Exists(QY_JK_API_ROOT.'exit', 'file') ? true : false;
119 }
120
121 //载入任务包
122 public function LoadTask()
123 {
124 if(count($this -> CurrentList) < 1 && count($this -> TaskPackag) > 0){
125 $TaskPackKey = key($this -> TaskPackag);
126 $this -> CurrentPackId = intval($TaskPackKey);
127 $this -> TaskList = $this -> TaskPackag[$TaskPackKey]['tl_list'];
128 unset($this -> TaskPackag[$TaskPackKey]);
129 if(IsType($this -> TaskList, 'array')) return true;
130 }
131 return false;
132 }
133
134 //任务处理结果
135 public function Result()
136 {
137 while(true){
138 if($this -> IsExit())
139 {
140 break;
141 exit;
142 }
143 //子进程执行完成
144 if(count($this -> CurrentList) < 1)
145 {
146 $this -> ReceiveTaskPack($this -> CurrentPackId); //发送结果到服务
147 $this -> CurrentPackId = 0;
148 $this -> LoadTask(); //载入新任务包
149 $this -> ExecRun(); //启动线程任务
150 $this -> ReadTask();
151 }
152 usleep(100);
153 }
154 }
155
156 //开线程
157 protected function ToFork($TaskVal, $PackId)
158 {
159 if(!isset($TaskVal['TYPE'])||!isset($TaskVal['VALUE'])) return true;
160 $Pid = pcntl_fork();
161 if($Pid == -1)
162 { //运行失败
163 return false;
164 }else if($Pid){
165 //父进程
166 $this -> CurrentList[$Pid] = $TaskVal;
167 if(isset($this -> SignalList[$Pid]))
168 {
169 $this -> ChildSgHand(SIGCHLD, $Pid, $this -> SignalList[$Pid]);
170 unset($this -> SignalList[$Pid]);
171 }
172 }else{
173 //子进程-处理任务
174 $Server = new server();
175 $TaskData = array();
176 switch(strtolower(trim($TaskVal['TYPE'])))
177 {
178 case 'ping' : {
179 $TaskData = $Server -> GetPing($TaskVal['VALUE'], isset($TaskVal['COUNT'])?$TaskVal['COUNT']:NULL);
180 break;
181 }
182 case 'smtp' : {
183 $TaskData = $Server -> GetSmtp($TaskVal['VALUE'], isset($TaskVal['PORT'])?$TaskVal['PORT']:NULL);
184 break;
185 }
186 case 'udp' : {
187 $TaskData = $Server -> GetUdp($TaskVal['VALUE'], isset($TaskVal['PORT'])?$TaskVal['PORT']:NULL, isset($TaskVal['SEND'])?$TaskVal['SEND']:NULL, isset($TaskVal['BACK'])?$TaskVal['BACK']:NULL);
188 break;
189 }
190 case 'tcp' : {
191 $TaskData = $Server -> GetTcp($TaskVal['VALUE'], isset($TaskVal['PORT'])?$TaskVal['PORT']:NULL);
192 break;
193 }
194 case 'http' : {
195 $TaskData = $Server -> GetHttp($TaskVal['VALUE']);
196 break;
197 }
198 case 'https' : {
199 $TaskData = $Server -> GetHttps($TaskVal['VALUE']);
200 break;
201 }
202 case 'ftp' : {
203 $TaskData = $Server -> GetFtp($TaskVal['VALUE'], isset($TaskVal['USER'])?$TaskVal['USER']:NULL, isset($TaskVal['PASS'])?$TaskVal['PASS']:NULL);
204 break;
205 }
206 case 'dns' : {
207 $TaskData = $Server -> GetDns($TaskVal['VALUE']);
208 break;
209 }
210 }
211 //记录数据结果
212 $this -> MysqlAddTaskResult($TaskVal, $PackId, $TaskData);
213 exit(0);
214 }
215 return true;
216 }
217
218 //读取任务包
219 public function MysqlReadTaskPack($Size=1)
220 {
221 //获取数据库连接
222 $DBLink = MysqlGetLink();
223 if(!$DBLink) return false;
224 $sql = 'select * from '.MysqlGetTab('task_list').' where tl_state=0 limit 0 , '.@intval($Size);
225 $result = false;
226 if(!$result = mysql_query($sql, $DBLink)) return false;
227 $return = false;
228 while($array = mysql_fetch_array($result))
229 {
230 $return[] = array('tl_sysid' => $array['tl_sysid'], 'tl_sum' => $array['tl_sum'], 'tl_list' => unserialize($array['tl_list']));
231 }
232 mysql_close($DBLink);
233 return $return;
234 }
235
236 //添加任务结果Mysql
237 public function MysqlAddTaskResult($TaskVal, $PackId, $TaskData)
238 {
239 //获取数据库连接
240 $DBLink = MysqlGetLink();
241 if(!$DBLink) return false;
242 $sql = 'insert into '.MysqlGetTab('task_result').' (tr_sysid, tr_tl_sysid, tr_data, tr_result, tr_state) values ('.$TaskVal['sysid'].','.$PackId.',\''.serialize($TaskVal).'\',\''.serialize($TaskData).'\',0)';
243 if(!mysql_query($sql, $DBLink)) return false;
244 mysql_close($DBLink);
245 return true;
246 }
247
248 //发回任务包
249 public function ReceiveTaskPack($PackId)
250 {
251 $PackId = @intval($PackId);
252 if($PackId < 1) return false;
253 //获取数据库连接
254 $DBLink = MysqlGetLink();
255 if(!$DBLink) return false;
256 $sql = 'update '.MysqlGetTab('task_list').' set tl_state=1 where tl_sysid=\''.$PackId.'\' and tl_state=2';
257 if(!mysql_query($sql, $DBLink)) return false;
258 $sql = 'select * from '.MysqlGetTab('task_result').' where tr_tl_sysid='.$PackId.' and tr_state=0';
259 $result = false;
260 if(!$result = mysql_query($sql, $DBLink)) return false;
261 $return = false;
262 $resultdata = $tmpdata = array();
263 while($array = mysql_fetch_array($result))
264 {
265 $tmpdata = unserialize($array['tr_data']);
266 $tmpdata['DATA'] = unserialize($array['tr_result']);
267 $resultdata[] = $tmpdata;
268 $tmpdata = array();
269 }
270 $sql = 'update '.MysqlGetTab('task_result').' set tr_state=1 where tr_tl_sysid='.$PackId.' and tr_state=0';
271 if(!mysql_query($sql, $DBLink)) return false;
272 $param = array(
273 'action' => 'sendtaskresult',
274 //任务id
275 'taskid' => $PackId,
276 'tasksum' => count($resultdata),
277 'tasklist' => serialize($resultdata)
278 );
279 $this -> SendResult($DBLink, $param, $PackId, 1); //处理发送回服务器结果
280 return true;
281 }
282
283 //处理发送回服务器结果
284 public function SendResult($DBLink, $param, $PackId, $Count)
285 {
286 try{
287 $result = receive($param);
288 if(strlen($result['type']) == 3)
289 {
290 if($result['type']{0} == '2') //成功
291 {
292 if($result['data']['checktaskresult'])
293 {
294 $sql = 'delete from '.MysqlGetTab('task_list').' where tl_sysid=\''.$PackId.'\' and tl_state=1';
295 if(!mysql_query($sql, $DBLink)) return false;
296 $sql = 'delete from '.MysqlGetTab('task_result').' where tr_tl_sysid='.$PackId.' and tr_state=1';
297 if(!mysql_query($sql, $DBLink)) return false;
298 }
299 }
300 elseif($result['type']{0} == '4') //失败
301 {
302 if($Count < $this -> MaxRetryNum) $this -> SendResult($param, $PackId, $Count++);
303 }
304 }
305 }catch(Exception $E){
306 //die($E -> getMessage());
307 }
308 if(isset($DBLink) && $DBLink) mysql_close($DBLink);
309 }
310 }

 

posted @ 2012-01-17 16:04  祥辉  阅读(338)  评论(0编辑  收藏  举报