承接 reptily/async-run 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

reptily/async-run

Composer 安装命令:

composer require reptily/async-run

包简介

Library for asynchronous launch

README 文档

README

composer require reptily/async-run

Example use as object

Example file: /example/async_run.php

This library provides several methods for working with asynchronicity.

When an object is initialized in the constructor, parameters are available.

new AsyncRun(
    int $coresCount = 1,             // Count of running threads
    string $pathTmpDir = '/tmp',     // path to temporary files directory
    ?string $lockFileName = null     // filename for locale
);

Example use as callbacks

Example file: /example/async.php

You can easily use the library within your code.

To do this, fill in the necessary functions in the run(...function) method

After this, all the functions specified in run() will be executed, if there is success, then() will be called, if there is an error, catch() will be called, the finally() method will be called in any of the above cases.

Async::run(
    function () {
        sleep(1);
        echo "AAA" . PHP_EOL;
    },
    function () {
        echo "BBB" . PHP_EOL;
    }
)->then(function () {
    echo "CCC" . PHP_EOL;
})->finally(function () {
    echo "DDD" . PHP_EOL;
})->catch(function ($errorText) {
    echo "Error " . $errorText . PHP_EOL;
});

Example with Shared Memory and Mutex

Example file: /example/async_memory.php

This example demonstrates how to use shared memory and mutex for thread-safe operations in asynchronous execution.

Performance Note: In SharedMemoryContainer, both numeric and string keys can be used with get() and set() methods, but using numeric keys provides better performance.

$fns = [];
for ($i = 1; $i <= 500; $i++) {
    $fns[] = function (SharedMemoryContainer $memory, Mutex $mutex) {
        $mutex->lock();
        $data = $memory->get('transaction') ?? ['moneySeller' => 0 , 'moneyBuyer' => 1000];
        $data['moneySeller']++;
        $data['moneyBuyer']--;
        $memory->set('transaction', $data);
        $mutex->unlock();
    };
}

Async::run(...$fns)->finally(function (array $memory) {
    var_dump($memory);
    /*
    array(1) {
        'transaction' =>
            array(2) {
                'moneySeller' => int(500)
                'moneyBuyer' => int(500)
            }
    }
    */
});

Example: Race Conditions and Solutions

Example file: /example/async_race_conditions.php

This example demonstrates race conditions in concurrent programming and shows how to solve them using mutex locks.

Problem 1: Variable scope issues

$fns = [];
$money = 0;
for ($i = 1; $i <= 1000; $i++) {
    $fns[] = function () use (&$money){
        $money++;
    };
}
Async::run(...$fns);
echo $money . PHP_EOL; // 0 -> error (variable scope issue)

Problem 2: Race conditions with shared memory

$fns = [];
for ($i = 1; $i <= 1000; $i++) {
    $fns[] = function (SharedMemoryContainer $memory) {
        $money = $memory->get(1) ?? 0;
        $money++;
        $memory->set(1, $money);
    };
}
Async::run(...$fns)->finally(function (array $memory) {
    echo $memory[1] . PHP_EOL; // 998 != 1000 (race condition)
});

Solution: Using Mutex for thread-safe operations

$fns = [];
for ($i = 1; $i <= 1000; $i++) {
    $fns[] = function (SharedMemoryContainer $memory, Mutex $mutex) {
        $mutex->lock();
        $money = $memory->get(1) ?? 0;
        $money++;
        $memory->set(1, $money);
        $mutex->unlock();
    };
}
Async::run(...$fns)->finally(function (array $memory) {
    echo $memory[1] . PHP_EOL; // 1000 (correct result)
});

Methods

init - Object initialization method, used for prelaunch configuration.

protected function init(): void
{
    $this->arrayTest = [
        [self::FIELD_NAME => 'Bob'],
        [self::FIELD_NAME => 'Mark'],
        [self::FIELD_NAME => 'Ana'],
    ];
}

getError - Error return method.

protected function getError(string $message): void
{
    print_r($message);
}

done - The method is run after the entire execution, as a rule, it serves to generate a report.

protected function done(): void
{
    echo "Done in " . $this->getProgressTime() . " sec.\n";
}

unlock - Method for pre-unblocking.

(new Example(2))->unlock();

run - Method to run handlers.

(new Example(2))->run();

workerAfterSpawn - Method starts before each worker and distributes tasks to them.

protected function workerAfterSpawn(): void
{
    next($this->arrayTest);
}

getWorkerResults - The method returns the result of the worker's work.

protected function getWorkerResults(): void
{
    $item = current($this->arrayTest);
    echo $item[self::FIELD_NAME] . "\n";
}

getWorkerDoneCondition - The method serves as a pointer to the completion of processing all jobs.

protected function getWorkerDoneCondition(): bool
{
    return current($this->arrayTest) === false;
}

统计信息

  • 总下载量: 6
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 3
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: GPL-3.0-or-later
  • 更新时间: 2022-05-05

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固