Как я возвращаю информацию 'в реальном времени' от подпроцесса. Popen в Python (2.5)

В качестве другой альтернативы, если вам действительно нужно использовать инжекцию зависимости в модели, не касаясь метода __construct

Вы можете использовать черту , которая будет Разрешите это для вашей модели

namespace App\Traits;

use Illuminate\Http\Request;
trait InjectRequest
{
    public static $request;

    protected static function bootInjectRequest()
    {
        self::$request = app(Request::class);
    }

    public function request(): Request
    {
        return self::$request;
    }
}

На вашей модели:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use App\Traits\InjectRequest;

class Conference_list extends Model
{
    use InjectRequest;
    public $timestamps = false;

}

Назовите вашу модель:

$request = (new App\Models\Conference_list())->request(); 

Узнайте больше о загрузочных чертах: https://www.archybold.com/blog/post/booting-eloquent-model-traits

46
задан Robert 3 July 2015 в 10:32
поделиться

7 ответов

stdout будет буферизирован, поэтому вы ничего не получите, пока этот буфер не будет заполнен или пока подпроцесс не завершится.

Вы можете попробовать сбросить stdout из подпроцесса. -process, или использование stderr, или изменение stdout в небуферизованном режиме.

7
ответ дан 26 November 2019 в 20:43
поделиться

Update with code that appears not to work (on windows anyway)

class ThreadWorker(threading.Thread):
    def __init__(self, callable, *args, **kwargs):
        super(ThreadWorker, self).__init__()
        self.callable = callable
        self.args = args
        self.kwargs = kwargs
        self.setDaemon(True)

    def run(self):
        try:
            self.callable(*self.args, **self.kwargs)
        except wx.PyDeadObjectError:
            pass
        except Exception, e:
            print e



if __name__ == "__main__":
    import os
    from subprocess import Popen, PIPE

    def worker(pipe):
        while True:
            line = pipe.readline()
            if line == '': break
            else: print line

    proc = Popen("python subprocess_test.py", shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)

    stdout_worker = ThreadWorker(worker, proc.stdout)
    stderr_worker = ThreadWorker(worker, proc.stderr)
    stdout_worker.start()
    stderr_worker.start()
    while True: pass
8
ответ дан 26 November 2019 в 20:43
поделиться

Похоже, проблема может заключаться в использовании буферизованного вывода подпроцессом - если создается относительно небольшой объем вывода, он может буферизоваться до тех пор, пока подпроцесс не завершится. Некоторую предысторию можно найти здесь :

2
ответ дан 26 November 2019 в 20:43
поделиться

Я использовал для этого модуль pexpect, похоже, он работает нормально. http://sourceforge.net/projects/pexpect/

0
ответ дан 26 November 2019 в 20:43
поделиться

Вот что мне помогло:

cmd = ["./tester_script.bash"]
p = subprocess.Popen( cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
while p.poll() is None:
    out = p.stdout.readline()
    do_something_with( out, err )

В вашем случае вы можете попробовать передать ссылку на подпроцесс своей Рабочей Нити, и провести опрос внутри потока. Я не знаю, как он будет себя вести, когда два потока опрашивают (и взаимодействуют) с одним и тем же подпроцессом, но это может сработать.

Также обратите внимание на то, что , в то время как p.poll() равно None: предназначено "как есть". Нене ли заменить его на , а не p.poll(), как в питоне 0 (код возвращения к успешному завершению) также считается Ложным.

.
2
ответ дан 26 November 2019 в 20:43
поделиться

Я тоже столкнулся с этой проблемой. Проблема возникает потому, что вы пытаетесь прочитать и stderr. Если ошибок нет, то попытка чтения из stderr блокируется.

В Windows нет простого способа опросить() файловые дескрипторы (только сокеты Winsock).

Так что решение состоит в том, чтобы не пытаться читать из stderr.

1
ответ дан 26 November 2019 в 20:43
поделиться

Использование pexpect [http://www.noah.org/wiki/Pexpect] с неблокирующими readlines решит эту проблему. Это происходит из-за того, что трубы буферизуются, и поэтому вывод вашего приложения буферизуется трубой, поэтому вы не можете получить этот вывод, пока буфер не заполнится или процесс не умрет.

1
ответ дан 26 November 2019 в 20:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: