三十三、Swoole 基础学习笔记 - Swoole 系统 API
hi,我是温新,一名PHPer
文章基于 Swoole 5.0.1 版本编写。
学习目标:了解系统 API
说明:本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!
Coroutine\System
系统相关 API
的协程封装。大部分 API
基于 AIO
线程池实现。
官方推荐使用Co\System::sleep
或 Swoole\Coroutine\System::sleep
statvfs
含义:获取文件系统信息。
语法:
Swoole\Coroutine\System::statvfs(string $path): array|false
# 参数
$path:文件系统挂载的目录【如 /,可以使用 df 和 mount -l 命令获取】
案例:
Swoole\Coroutine\run(function () {
print_r(Swoole\Coroutine\System::statvfs('/usr/local/src'));
});
输出结果:
$php 33-swoole-system-api.php
Array
(
[bsize] => 4096
[frsize] => 4096
[blocks] => 51328506
[bfree] => 41599890
[bavail] => 38974354
[files] => 13107200
[ffree] => 12521751
[favail] => 12521751
[fsid] => 3942528374396710653
[flag] => 4096
[namemax] => 255
)
fwrite
含义:协程方式向文件写入数据。
语法:
Swoole\Coroutine\System::fwrite(resource $handle, string $data, int $length = 0): int|false
# 参数
$handle:文件句柄【必须是 fopen 打开的文件类型 stream 资源】
$data:要写入的数据内容【可以是文本或二进制数据】
$length:读取的长度【默认为 0,表示写入 $data 的全部内容,$length 必须小于 $data 的长度】
案例:
$fp = fopen('test.txt', 'a+');
Swoole\Coroutine\run(function () use ($fp) {
$result = Swoole\Coroutine\System::fwrite($fp, '我叫王美丽');
var_dump($result);
});
fclose($fp);
fread
含义:协程方式读取文件。
语法:
Swoole\Coroutine\System::fread(resource $handle, int $length = 0): string|false
# 参数
$handle:文件句柄【必须是 fopen 打开的文件类型 stream 资源】
$length:读取的长度【默认为 0,表示读取文件的全部内容】
返回值:读取成功返回字符串内容,读取失败返回 false
案例:
$fp = fopen('test.txt', 'r');
Swoole\Coroutine\run(function () use ($fp) {
$result = Swoole\Coroutine\System::fread($fp);
// 读取的长度为字节
// $result = Swoole\Coroutine\System::fread($fp, 3);
var_dump($result);
});
fclose($fp);
fgets
含义:协程方式按行读取文件内容。
说明:底层使用了 php_stream
缓存区,默认大小为 8192
字节,可使用 stream_set_chunk_size
设置缓存区尺寸。
语法:
Swoole\Coroutine\System::fgets(resource $handle): string|false
# 返回值
读取到 EOL(\r 或 \n)将返回一行数据,包括 EOL;
未读取到 EOL,但内容长度超过 php_stream 缓存区 8192 字节,将返回 8192 字节的数据,不包含 EOL;
达到文件末尾 EOF 时,返回空字符串,可用 feof 判断文件是否已读完;
取失败返回 false。
案例
$fp = fopen('test.txt', 'r');
Swoole\Coroutine\run(function () use ($fp) {
while (!feof($fp)) {
echo Swoole\Coroutine\System::fgets($fp) . PHP_EOL;
}
});
fclose($fp);
readFile
含义:协程方式读取一个文件的内容。
语法:Swoole\Coroutine\System::readFile(string $filename): string|false
案例:
$file = 'test.txt';
Swoole\Coroutine\run(function () use ($file) {
$result = Swoole\Coroutine\System::readFile($file);
print_r($result);
$content = Swoole\Coroutine\System::readFile('test.txt');
print_r($content);
});
writeFiel
含义:协程方式写入文件。
语法:
Swoole\Coroutine\System::writeFile(string $filename, string $fileContent, int $flags): bool
# 参数
$filename:文件名【必须有可写权限,文件不存在会自动创建。打开文件失败会立即返回 false】;
$fileContent:写入到文件的内容【最大可写入 4M】;
$flags:写入的选项【默认会清空当前文件内容,可以使用 FILE_APPEND 表示追加到文件末尾】
案例:
Swoole\Coroutine\run(function () {
$content = Swoole\Coroutine\System::writeFile('baidu.txt', file_get_contents('https://www.baidu.com'));
var_dump($content);
});
sleep
含义:进入等待状态。
说明:相当于 PHP 中的 sleep 函数,不同的是 Coroutine::sleep 是协程调度器实现的,底层会 yield 当前协程,让出时间片,并添加一个异步定时器,当超时时间 到达时重新 resume 当前协程,恢复运行。使用 sleep
接口可以方便地实现超时等待功能。
语法:
Swoole\Coroutine\System::sleep(float $seconds): void
# 参数
$seconds:睡眠的时间【必须大于 0,最大不得超过一天时间(86400 秒)】
exec
含义:执行一条 sheel 指令。底层自动进行协程调度。
语法:Swoole\Coroutine\System::exec(string $cmd): array
案例:
Swoole\Coroutine\run(function() {
$ret = Swoole\Coroutine\System::exec('ls');
print_r($ret);
});
gethostbyname
含义:将域名解析为 IP。
语法:
Swoole\Coroutine\System::gethostbyname(string $domain, int $family = AF_INET, float $timeout = -1): string|false
# 参数
$domain:域名;
$family:域族;
$timeout:超时时间
案例:
Swoole\Coroutine\run(function() {
$ip = Swoole\Coroutine\System::gethostbyname('www.baidu.com');
var_dump($ip);
});
输出结果:
$php 33-swoole-system-api.php
string(13) "14.215.177.38"
getaddrinfo
含义:进行 DNS 解析,查询域名对应的 IP 地址。与 gethostbyname
不同,getaddrinfo
支持更多参数设置,而且会返回多个 IP
结果。
语法:
Swoole\Coroutine\System::getaddrinfo(string $domain, int $family = AF_INET, int $socktype = SOCK_STREAM, int $protocol = STREAM_IPPROTO_TCP, string $service = null, float $timeout = -1): array|false
# 参数
$domain:域名;
$family:域族【AF_INET 表示返回 IPv4 地址,使用 AF_INET6 时返回 IPv6 地址】;
$socktype :协议类型;
$protocol : 协议;
$service:
$timeout:超时时间
案例:
Swoole\Coroutine\run(function() {
$ret = Swoole\Coroutine\System::getaddrinfo('www.baidu.com');
var_dump($ret);
});
输出结果:
$php 33-swoole-system-api.php
array(2) {
[0]=>
string(13) "14.215.177.38"
[1]=>
string(13) "14.215.177.39"
}
wait
含义:对应原有的 Process:wait
,不同的是此 API 是协程版本,会造成协程挂起,可替换 Swoole\Process::wait
和 pcntl_wait
函数。
语法:Swoole\Coroutine\System::wait(float $timeout = -1): array|false
每个子进程启动后,父进程必须都要派遣一个协程调用
wait()
(或waitPid()
) 进行回收,否则子进程会变成僵尸进程,会浪费操作系统的进程资源。 如果使用了协程,必须是先创建进程,进程里面再开协程。而不是反过来,否则就是带着协程 fork 情况会非常复杂,导致底层很难处理。
waitPid
含义:和上述 wait 方法基本一致,不同的是此 API 可以指定等待特定的进程。
语法:
Swoole\Coroutine\System::waitPid(int $pid, float $timeout = -1): array|false
# 参数
$pid:进程 id
案例:
$process = new Swoole\Process(function () {
echo 'Hello Swoole' . PHP_EOL;
});
$process->start();
Swoole\Coroutine\run(function () use ($process) {
$status = Swoole\Coroutine\System::waitPid($process->pid);
print_r($status);
});
输出结果:
$php 33-swoole-system-api.php
Hello Swoole
Array
(
[pid] => 34944
[code] => 0
[signal] => 0
)
我是温新,本篇文章结束。