6

经过数月的开发和测试工作,Swoole v6 的第一个版本终于发布了。
Swoole v6 将为 PHP 带来稳定可靠、生产可用的多线程方案。欢迎各位进行试用,为我们提交测试报告和问题反馈。

新特性:

  • 支持多线程模式,当phpzts模式,开启--enable-swoole-thread 即可使用
  • 新增线程管理类 Swoole\Thread @matyhtf
  • 新增线程锁 Swoole\Thread\Lock @matyhtf
  • 新增线程原子计数 Swoole\Thread\AtomicSwoole\Thread\Atomic\Long @matyhtf
  • 新增安全并发容器 Swoole\Thread\MapSwoole\Thread\ArrayListSwoole\Thread\Queue @matyhtf
  • 文件异步操作支持iouring作为底层引擎 @matyhtf @NathanFreeman
  • 升级 Boost Context 版本到 1.84,现在,龙芯CPU也能够支持协程了 @NathanFreeman

示例:

创建线程:

use Swoole\Thread;

$args = Thread::getArguments(); // 如果是主线程,$args 为空,如果是子线程,$args 不为空
$c = 4;

if (empty($args)) {
    # 主线程
    for ($i = 0; $i < $c; $i++) {
        $threads[] = new Thread(__FILE__, $i);
    }
    for ($i = 0; $i < $c; $i++) {
        $threads[$i]->join();
    }
} else {
    # 子线程
    echo "Thread #" . $args[0] . "\n";
    while (1) {
        sleep(1);
        file_get_contents('https://www.baidu.com/');
    }
}

线程 + 服务端(异步风格)

use Swoole\Process;
use Swoole\Thread;
use Swoole\Http\Server;

$http = new Server("0.0.0.0", 9503, SWOOLE_THREAD);
$http->set([
    'worker_num' => 2,
    'task_worker_num' => 3,
    'bootstrap' => __FILE__,
    // 通过init_arguments实现线程间的数据共享。
    'init_arguments' => function () use ($http) {
        $map = new Swoole\Thread\Map;
        return [$map];
    }
]);

$http->on('Request', function ($req, $resp) use ($http) {
    $resp->end('hello world');
});

$http->on('pipeMessage', function ($http, $srcWorkerId, $msg) {
    echo "[worker#" . $http->getWorkerId() . "]\treceived pipe message[$msg] from " . $srcWorkerId . "\n";
});

$http->addProcess(new Process(function () {
   echo "user process, id=" . Thread::getId();
   sleep(2000);
}));

$http->on('Task', function ($server, $taskId, $srcWorkerId, $data) {
    var_dump($taskId, $srcWorkerId, $data);
    return ['result' => uniqid()];
});

$http->on('Finish', function ($server, $taskId, $data) {
    var_dump($taskId, $data);
});

$http->on('WorkerStart', function ($serv, $wid) {
    // 通过Swoole\Thread::getArguments()获取配置中的init_arguments传递的共享数据
    var_dump(Thread::getArguments(), $wid);
});

$http->on('WorkerStop', function ($serv, $wid) {
    var_dump('stop: T' . Thread::getId());
});

$http->start();

Thread + Coroutine 在线程中使用协程

use Swoole\Thread;

$args = Thread::getArguments(); // If it is main thread, the $args is empty; if it is a child thread, the $args is not empty.
$c = 4;

if (empty($args)) {
    # main thread
    for ($i = 0; $i < $c; $i++) {
        $threads[] = new Thread(__FILE__, $i);
    }
    for ($i = 0; $i < $c; $i++) {
        $threads[$i]->join();
    }
} else {
    # child thread x 4
    echo "Thread #" . $args[0] . "\n";
    Co\run(function() {
       while (1) {
          sleep(1);
          Co\go(function () {
              file_get_contents('https://www.baidu.com/');
          });
      }
    });
}

并发 Map

use Swoole\Thread;
$args = Thread::getArguments();

if (empty($args)) {
    $array = [
        'a' => random_int(1, 999999999999999999),
        'b' => random_bytes(128),
        'c' => uniqid(),
        'd' => time(),
    ];

    $map = new Thread\Map($array);
    $thread = new Thread(__FILE__, $map);
} else {
    $map = $args[0];
    var_dump($map->toArray());
}

Bug修复:

  • 修复无法通过 pecl 安装的问题 @remicollet
  • 修复Swoole\Coroutine\FastCGI\Client客户端无法设置keepalive @NathanFreeman
  • 修复请求参数超过max_input_vars时会抛出错误导致进程不断重启的问题 @NathanFreeman
  • 修复在协程中使用Swoole\Event::wait()导致的未知问题 @matyhtf
  • 修复proc_open在协程化的时候不支持pty的问题 @matyhtf
  • 修复pdo_sqlitePHP8.3会出现段错误的问题 @NathanFreeman
  • 修复编译时的无用警告 @Appla @NathanFreeman
  • 修复如果STDOUT/STDERR已经关闭时,底层调用zend_fetch_resource2_ex会抛出错误 @Appla @matyhtf
  • 修复无效的set_tcp_nodelay配置 @matyhtf
  • 修复文件上传的时候偶尔会触发不可达的分支问题 @NathanFreeman
  • 修复设置了dispatch_func 导致php底层抛出错误的问题 @NathanFreeman
  • 修复AC_PROG_CC_C99autoconf >= 2.70版本中已过时 @petk
  • 当线程创建失败时,捕获其抛出的异常 @matyhtf
  • 修复_tsrm_ls_cache未定义问题 @jingjingxyk
  • 修复在GCC 14编译会导致致命错误 @remicollet

内核优化:

  • 移除对socket structs的无用检查 @petk
  • 升级swoole Library @deminy
  • Swoole\Http\Response增加对451状态码的支持 @abnegate
  • 同步PHP不同版本的文件操作代码 @NathanFreeman
  • 同步PHP不同版本的pdo操作代码 @NathanFreeman
  • 优化Socket::ssl_recv()的代码 @matyhtf
  • 优化了config.m4,一些配置可以通过pkg-config设置依赖库位置 @NathanFreeman
  • 优化解析请求头的时候使用动态数组的问题 @NathanFreeman
  • 优化在多线程模式下,文件描述符fd的生命周期问题 @matyhtf
  • 优化协程一些基本逻辑 @matyhtf

废弃:

  • 不再支持PHP 8.0
  • 不再支持Swoole\Coroutine\MySQL协程客户端
  • 不再支持Swoole\Coroutine\Redis协程客户端
  • 不再支持Swoole\Coroutine\PostgreSQL协程客户端

韩天峰
7.9k 声望11.1k 粉丝

Swoole 开源项目创始人