how to do a non-blocking fgets?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tanel

    #1

    how to do a non-blocking fgets?

    Hello,

    I need to read a result of the first script (that takes some time to
    run) from the second script so that the first script doesn't block the
    second. Here is a short example. do_smth_else() should be called
    during test.php's sleep, instead the first fgets blocks the processing
    of the parent script and do_smth_else is called only once. How can I
    do a non-blocking fgets()? I use php 4.3.4 on windows xp

    $process = popen("c:\php\p hp -f test.php", 'r');
    stream_set_bloc king($process, false);
    do {
    $line = fgets($process) ;
    print $line;
    do_smth_else();
    if ($line === false) break;
    } while(true);
    pclose($process );

    contents of the test.php:
    <?php echo 'Hello';sleep(2 ); echo ' World!'; ?>
  • CountScubula

    #2
    Re: how to do a non-blocking fgets?

    "Tanel" <rik447@hot.e e> wrote in message
    news:9957109e.0 401190551.5cef4 512@posting.goo gle.com...[color=blue]
    > Hello,
    >
    > I need to read a result of the first script (that takes some time to
    > run) from the second script so that the first script doesn't block the
    > second. Here is a short example. do_smth_else() should be called
    > during test.php's sleep, instead the first fgets blocks the processing
    > of the parent script and do_smth_else is called only once. How can I
    > do a non-blocking fgets()? I use php 4.3.4 on windows xp
    >
    > $process = popen("c:\php\p hp -f test.php", 'r');
    > stream_set_bloc king($process, false);
    > do {
    > $line = fgets($process) ;
    > print $line;
    > do_smth_else();
    > if ($line === false) break;
    > } while(true);
    > pclose($process );
    >
    > contents of the test.php:
    > <?php echo 'Hello';sleep(2 ); echo ' World!'; ?>[/color]

    sounds like you are a VB programmer looking for doevents() or you want to
    spawn a background thread.

    To the best of my knowlendge there is no *simple* way of doing multithreads
    *within* a php script.

    my advice, rethink what you are trying to acomplish, and shell out of the
    script and launch a new proccess in the background: `php -q script.php &`;


    --
    Mike Bradley
    http://www.gzentools.com -- free online php tools


    Comment

    • martin

      #3
      Re: how to do a non-blocking fgets?

      rik447@hot.ee (Tanel) wrote in message news:<9957109e. 0401190551.5cef 4512@posting.go ogle.com>...[color=blue]
      > Hello,
      >
      > I need to read a result of the first script (that takes some time to
      > run) from the second script so that the first script doesn't block the
      > second. Here is a short example. do_smth_else() should be called
      > during test.php's sleep, instead the first fgets blocks the processing
      > of the parent script and do_smth_else is called only once. How can I
      > do a non-blocking fgets()? I use php 4.3.4 on windows xp
      >
      > $process = popen("c:\php\p hp -f test.php", 'r');
      > stream_set_bloc king($process, false);
      > do {
      > $line = fgets($process) ;
      > print $line;
      > do_smth_else();
      > if ($line === false) break;
      > } while(true);
      > pclose($process );
      >
      > contents of the test.php:
      > <?php echo 'Hello';sleep(2 ); echo ' World!'; ?>[/color]

      Are you sure it's blocking and not just looping once? I get
      do_smth_else() being called once, but also no "Hello World" and
      with fgets() returning "false" the first time, as expected. It
      works for me without the "if ($line == false) break;" line and
      with "while(!feof($p rocess))" instead of "while(true )"

      Comment

      • Tanel

        #4
        Re: how to do a non-blocking fgets?

        mcompengr@earth link.net (martin) wrote in message >[color=blue]
        > Are you sure it's blocking and not just looping once? I get
        > do_smth_else() being called once, but also no "Hello World" and
        > with fgets() returning "false" the first time, as expected. It
        > works for me without the "if ($line == false) break;" line and
        > with "while(!feof($p rocess))" instead of "while(true )"[/color]

        Notice the three = in ($line === false). Here is maybe a better
        example to show what I mean. The first fgets waits until the test.php
        has finished, and second fgets has nothing. Desired behavior should be
        1st fgets:Hello, 2nd fgets World!

        $process = popen("c:\php\p hp -f test.php", 'r');
        stream_set_bloc king($process, false);
        print "\n 1st fgets:".fgets($ process);
        sleep(3);
        print "\n 2nd fgets:".fgets($ process);
        pclose($process );

        Comment

        • Tanel

          #5
          Re: how to do a non-blocking fgets?

          "CountScubu la" <me@scantek.hot mail.com> wrote in message news:<6HXOb.134 33[color=blue]
          > To the best of my knowlendge there is no *simple* way of doing multithreads
          > *within* a php script.
          >
          > my advice, rethink what you are trying to acomplish, and shell out of the
          > script and launch a new proccess in the background: `php -q script.php &`;[/color]

          I am trying to make a php-gtk utility which uses curl to get some web
          content. So far the curl_exec blocks the whole script (until download
          is finished) and gui freezes. I also need to start to download a
          second page before the first is finished, so I have multiple streams I
          need to check for arriving data. All that time the gui should be
          responsive. It seams that its not an easy task in php..

          Comment

          • CountScubula

            #6
            Re: how to do a non-blocking fgets?

            "Tanel" <rik447@hot.e e> wrote in message
            news:<9957109e. 0401200459.63b0 23f6@posting.go ogle.com>...[color=blue]
            > "CountScubu la" <me@scantek.hot mail.com> wrote in message news:<6HXOb.134 33[color=green]
            > > To the best of my knowlendge there is no *simple* way of doing[/color][/color]
            multithreads[color=blue][color=green]
            > > *within* a php script.
            > >
            > > my advice, rethink what you are trying to acomplish, and shell out of[/color][/color]
            the[color=blue][color=green]
            > > script and launch a new proccess in the background: `php -q script.php[/color][/color]
            &`;[color=blue]
            >
            > I am trying to make a php-gtk utility which uses curl to get some web
            > content. So far the curl_exec blocks the whole script (until download
            > is finished) and gui freezes. I also need to start to download a
            > second page before the first is finished, so I have multiple streams I
            > need to check for arriving data. All that time the gui should be
            > responsive. It seams that its not an easy task in php..[/color]

            if this is a shell script with gui front, then it might be easier to launch
            other proccesses instead of trying to multithread. launch your get php
            script with
            `php -q script.php $url &`;
            or
            `wget $url &`;

            both will run in background while your gui is active.

            --
            Mike Bradley
            http://www.gzentools.com -- free online php tools


            Comment

            • martin

              #7
              Re: how to do a non-blocking fgets?

              rik447@hot.ee (Tanel) wrote in message news:<9957109e. 0401200434.50da fd6d@posting.go ogle.com>...[color=blue]
              > mcompengr@earth link.net (martin) wrote in message >[color=green]
              > > Are you sure it's blocking and not just looping once? I get
              > > do_smth_else() being called once, but also no "Hello World" and
              > > with fgets() returning "false" the first time, as expected. It
              > > works for me without the "if ($line == false) break;" line and
              > > with "while(!feof($p rocess))" instead of "while(true )"[/color]
              >
              > Notice the three = in ($line === false).[/color]

              Same difference. "false" is the empty string. fgets() returns
              an empty string when reading from a non-blocking file-descriptor
              which has nothing to read. "if ($line === false) break;" will
              surely break out of your loop when $line comes from such a read,
              as it surely must for at least the first read. Fgets() will not
              wait for anything when reading from a non-blocking file-descriptor.

              If, as you said, you want to "read a result of the first script
              (that takes some time to run) from the second script so that the
              first script doesn't block the second", and meanwhile be doing
              something else, this will do that for you until the first script
              is finished. (your example code modified):

              $process = popen("c:\php\p hp -f test.php", 'r');
              stream_set_bloc king($process, false);
              do {
              $line = fgets($process) ;
              do_something_wi th_line($line);
              do_something_el se();
              } while(!feof($pr ocess));
              pclose($process );

              [color=blue]
              > Here is maybe a better
              > example to show what I mean. The first fgets waits until the test.php
              > has finished, and second fgets has nothing. Desired behavior should be
              > 1st fgets:Hello, 2nd fgets World!
              >
              > $process = popen("c:\php\p hp -f test.php", 'r');
              > stream_set_bloc king($process, false);
              > print "\n 1st fgets:".fgets($ process);
              > sleep(3);
              > print "\n 2nd fgets:".fgets($ process);
              > pclose($process );[/color]

              Comment

              Working...