php - 用PHP线程打开文件

标签 php regex multithreading file-io pthreads

我们有一个巨大的文本文件(大约1个演出),我们想用php搜索它,
为此,我用一些线程打开了本文的某些部分,并在这部分中进行了搜索。
像下面这样:

class AsyncFileRequest extends Thread
{   public $from_line;
    public $to_line;
    public $line;
    public $n;
    public $ans;
    public $handle;
        public function __construct($handle,$from_line,$to_line) {
        $this->handle =$handle = @fopen($handle, 'r');
        $this->from_line =$from_line;
        $this->to_line =$to_line;
    }    
    public function run() {
        if (($handle = $this->handle) &&
            ($from_line = $this->from_line) &&
            ($to_line = $this->to_line) 
            ) {       
            $n=0;
            $ans="";
            while($line=stream_get_line($handle,65535,"\n")) {

                $n++;
                if($n>=$from_line){
                    $ans.=$line;
                }
                if ($n == $to_line) {
                    break;
                }
             }
             fclose($handle);
             $this->data=$ans;
        } else printf("Thread #%lu was not provided a URL<br>\n", $this->getThreadId());
    }
}

但是,如果我用更多的时间来打开它,要花很长时间来处理,我们该如何用php线程来逐步打开大文件?

最佳答案

您想要在run方法中打开该句柄,这样可以确保每个线程都对该文件具有唯一的句柄。

线程将起作用,但是优选使用Pools执行模型。让Pool决定要在哪个线程中执行,对硬件和任务使用合理大小的Pool,并继续提交任务,直到完成所有工作为止。

然后等待池关闭,您可以使用Pool::collect从任务中获取数据。

例如:

<?php
/* A pooled task to read specific lines from a file */
class LineReader extends Collectable {

    public function __construct($file, $start, $lines) {
        $this->file  = $file;
        $this->start = $start;
        $this->lines = $lines;
    }

    public function run() {
        /* don't write the handle to the object scope */
        $handle = fopen($this->file, "r");
        $line   = 1;
        $count  = 0;

        while (($next = fgets($handle))) {
            if ($line >= $this->start) {
                if ($count < $this->lines) {
                    $lines .= $next;
                    $count++;
                } else break;
            }
            $line++;
        }

        $this->data = $lines;

        /* close handle */
        fclose($handle);

        /* finished with object */
        $this->setGarbage();
    }
}

$pool = new Pool(8);
/* submit enough tasks to read entire file */
$pool->submit(
    new LineReader(__FILE__, 1, 10));
$pool->submit(
    new LineReader(__FILE__, 10, 10));
$pool->submit(
    new LineReader(__FILE__, 20, 10));
$pool->submit(
    new LineReader(__FILE__, 30, 10));
$pool->submit(
    new LineReader(__FILE__, 40, 10));
$pool->submit(
    new LineReader(__FILE__, 50, 10));
$pool->submit(
    new LineReader(__FILE__, 60, 10));

/* force all reading to complete */
$pool->shutdown();

/* cleanup pool, and echo data to show working */
$pool->collect(function(LineReader $reader){
    foreach(preg_split("~\n~", $reader->data) as $line) {
        printf(
            "%04d: %s\n", $reader->start++, $line);
    }

    /* allow object to be free'd */
    return $reader->isGarbage();
});
?>

关于php - 用PHP线程打开文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27027542/

相关文章:

php - 在 yii2 查询构建器中如何使用带有 where 子句的运算符

php - 如何使用 1and1 数据库和 Dreamweaver 设置 PHP 发布日期?

javascript - 为什么这会导致浏览器锁定(我认为是无限循环)

正则表达式只允许 1 到 12 之间的数字

multithreading - 如何在多线程游戏引擎中保持我的世界数据同步?

php - 向自定义 WordPress 数据库表中的文本字段添加新行,而不覆盖现有值

javascript - 将文件上传到 HTML 表单并提交之间会发生什么?

java - 如何在 Java 中编写一个只允许数字 0-9 和 # 的正则表达式

Python 作用域和线程问题

java - 使用JAVA线程并发访问hsqldb