-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmpmt1.php
116 lines (106 loc) · 3.46 KB
/
mpmt1.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php
# mpmt1.tcl: A simple multi-threading/processing example in PHP
#
# License:
# Apache License, Version 2.0
# History:
# * 2024/12/07 v0.1 Initial version
# Author:
# Masanori Itoh <masanori.itoh@gmail.com>
# Dependency:
# * pcntl for multi-process
# * pthreads for multi-thread
# * parallel (maybe, not for now)
# Note:
# * Explore 'parallel' extension usage. Note that 'parallel' extension
# requires PHP 8.x. Also, I'm seeing an issue that parallel implemetation
# is executed only sequentially, meaning does not use multiple cores.
# It would be my misunderstanding, but I'm not sure why at the moment.
# The below (outedated) pthreads implementation works as expected.
# Usage:
# * `# php mpmt1.php [NUM_CONTEXT [DURATION [MODE]]]`
#
# References
# * https://www.php.net/manual/en/book.pcntl.php
# * https://www.php.net/manual/en/intro.parallel.php
# * https://www.php.net/manual/en/book.pthreads.php
# * https://www.php.net/manual/en/language.oop5.properties.php
#
$num_context = 3;
$duration = 5;
$mode = "p";
if (count($argv) > 1) {
$num_context = $argv[1];
}
if (count($argv) > 2) {
$duration = $argv[2];
}
if (count($argv) > 3) {
$mode = $argv[3];
}
printf("num_context: %d duration: %d mode: %s\n", $num_context, $duration, $mode);
$clist = array();
if ($mode == "p") {
for ($idx = 0; $idx < $num_context; $idx++) {
#printf("creating...: %d\n", $idx);
$pid = pcntl_fork();
if ($pid === 0) {
//child
$ts_start = microtime(true);
while (true) {
$ts_now = microtime(true);
if (($ts_now - $ts_start) > $duration) {
printf("Exiting...\n");
exit;
}
}
} else if ($pid === -1) {
//error
throw new RuntimeException('Failed to create a process');
} else {
//parent
array_push($clist, $pid);
}
}
foreach($clist as &$pid) {
$res = pcntl_waitpid($pid, $status);
#printf("%s %s %s\n", $res, $pid, $status);
}
} else if ($mode == "t") {
# The below uses outdated 'pthreads', not 'parallel'.
class Mpmt1 extends Thread
{
public $duration;
public function __construct(int $duration)
{
$this->duration = $duration;
}
public function run() {
#printf("in function. duration = %d\n", $this->duration);
$ts_start = microtime(true);
while (true) {
$ts_now = microtime(true);
if (($ts_now - $ts_start) > $this->duration) {
printf("Expired...\n");
break;
}
}
}
}
for ($idx = 0; $idx < $num_context; $idx++) {
#printf("creating...: %d\n", $idx);
$task = new Mpmt1($duration);
array_push($clist, $task);
}
foreach($clist as &$t) {
#printf("starting...: %s\n", $t->getThreadId());
$t->start();
}
foreach($clist as &$t) {
#printf("joining...: %s\n", $t->getThreadId());
$t->join();
}
} else {
printf("Unkown mode: %s\n", $mode);
}
?>