stderr, stdout, and errno 24

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

    #1

    stderr, stdout, and errno 24

    To capture output from python scripts run from a C++ app I've added the
    following code at the beggening of the C++ app:

    PyRun_SimpleStr ing("import grabber");
    PyRun_SimpleStr ing("import sys");
    PyRun_SimpleStr ing("class a:\n\tdef
    write(self,s):\ n\t\tograbber.g rab(s)\n");
    PyRun_SimpleStr ing("import sys\nsys.stderr =a()\nsys.stdou t=a()");

    Its hard to read that way, here's what it expands to:
    import grabber
    import sys
    class a:
    def write(self, s)
    grabber.grab(s)

    grabber is a C++ extension, the grab function prints displays the
    captured text in a Windows app. After running about 450+ scripts in a
    row, I get "IOError Errno 24 Too many open files."

    I've searched this group and the net and determined that stderr and
    stdout may open files, is that correct? If so would each running of a
    script be opening new files related to stderr and stdout and not
    closing them? I'm just guessing.

  • Dave Hansen

    #2
    Re: stderr, stdout, and errno 24

    On 12 Jul 2006 18:09:42 -0700 in comp.lang.pytho n, "Wesley Henwood"
    <wesleyhenwood@ hotmail.comwrot e:
    >To capture output from python scripts run from a C++ app I've added the
    >following code at the beggening of the C++ app:
    >
    >PyRun_SimpleSt ring("import grabber");
    >PyRun_SimpleSt ring("import sys");
    >PyRun_SimpleSt ring("class a:\n\tdef
    >write(self,s): \n\t\tograbber. grab(s)\n");
    >PyRun_SimpleSt ring("import sys\nsys.stderr =a()\nsys.stdou t=a()");
    >
    >Its hard to read that way, here's what it expands to:
    >import grabber
    >import sys
    >class a:
    def write(self, s)
    grabber.grab(s)
    Actually, that last line will more like
    ograbber.grab(s )
    At least, if what you posted above is accurate...

    It's not the question you asked, but if you want to make that easier
    to read, you can do something like

    PyRun_SimpleStr ing("import grabber");
    PyRun_SimpleStr ing("import sys");

    PyRun_SimpleStr ing("class a:\n"
    " def write(self,s):\ n"
    " grabber.grab(s) \n");

    PyRun_SimpleStr ing("import sys\n"
    "sys.stderr=a() \n"
    "sys.stdout=a() \n");


    C++, like Python, will concatenate strings seperated only by
    whitespace.

    Regards,
    -=Dave

    --
    Change is inevitable, progress is not.

    Comment

    • Jim Segrave

      #3
      Re: stderr, stdout, and errno 24

      In article <1152752982.418 243.236590@h48g 2000cwc.googleg roups.com>,
      Wesley Henwood <wesleyhenwood@ hotmail.comwrot e:
      >To capture output from python scripts run from a C++ app I've added the
      >following code at the beggening of the C++ app:
      >
      >PyRun_SimpleSt ring("import grabber");
      >PyRun_SimpleSt ring("import sys");
      >PyRun_SimpleSt ring("class a:\n\tdef
      >write(self,s): \n\t\tograbber. grab(s)\n");
      >PyRun_SimpleSt ring("import sys\nsys.stderr =a()\nsys.stdou t=a()");
      >
      >Its hard to read that way, here's what it expands to:
      >import grabber
      >import sys
      >class a:
      def write(self, s)
      grabber.grab(s)
      >
      >grabber is a C++ extension, the grab function prints displays the
      >captured text in a Windows app. After running about 450+ scripts in a
      >row, I get "IOError Errno 24 Too many open files."
      >
      >I've searched this group and the net and determined that stderr and
      >stdout may open files, is that correct? If so would each running of a
      >script be opening new files related to stderr and stdout and not
      >closing them? I'm just guessing.
      I'm guessing, but it sounds like perhaps you're creating an object which has
      an open file handle for output for each script that's run. When the
      script finishes, if that object still exists, it will keep a file
      handle open and eventually you'll hit the system limit on open file
      handles for one process.

      It's also possible that your C++ app is the one which is failing to
      close file handles created for running the scripts - there's no easy
      way to tell from the information posted.

      You need to examine carefully what happens to any stdin/stdout/stderr
      files which are created to execute scripts and ensure that they are
      all properly closed (or, in the case of Python, if you don't
      explicitly close them, that any references to the files cease to exist
      after the script runs). I'd personally recommend explicit closing
      here.




      --
      Jim Segrave (jes@jes-2.demon.nl)

      Comment

      • Wesley Henwood

        #4
        Re: stderr, stdout, and errno 24

        I've checked and double checked my code and I am closing all files
        explicitly after opening them. The only possibliy I can think of is
        Python opening files each time I run a script, or each time imput to
        stderr or stdout is redirected.

        Here's a link that is perhaps related to my
        problem:<http://pyfaq.infogami. com/why-doesn-t-closing-sys-stdout-stdin-stderr-really-close-it>

        Here is a thread in this group, see post by
        alisonken1:<htt p://groups.google.c om/group/comp.lang.pytho n/browse_thread/thread/75e65baa1a51b3a 6/512bba073992491 7?q=too+many+op en+files&rnum=2 0#512bba0739924 917>

        Comment

        • alisonken1

          #5
          Re: stderr, stdout, and errno 24


          Wesley Henwood wrote:
          I've checked and double checked my code and I am closing all files
          explicitly after opening them. The only possibliy I can think of is
          Python opening files each time I run a script, or each time imput to
          stderr or stdout is redirected.
          >
          <snip>

          The problem >I think< is that stout and stderr are not shared with each
          invocation.

          Since you're calling a python interpreter, the stdout/stderr from the
          C++ program is not inherited - so now everytime you call the python
          script, it's creating a new process.

          With each new process, you're creating a new stdout/stderr handle, and
          if you're calling outside of C++ relatively quickly (say more than 100
          times a minute), then the old stdout/stderr handles have not had a
          chance to be garbage collected - hence, you get too many files open
          errors.

          The workaround would possibly be to create a Python thread or create a
          stdout fifo and a stderr fifo and have your script redirect these
          outputs through the fifo buffers that you're C++ code can listen to.

          Not sure how to do either one in MS environments, so you'll have to ask
          someone else how to work with them.

          Comment

          • Lawrence D'Oliveiro

            #6
            Re: stderr, stdout, and errno 24

            In article <1152793219.333 586.59410@b28g2 000cwb.googlegr oups.com>,
            "Wesley Henwood" <wesleyhenwood@ hotmail.comwrot e:
            >I've checked and double checked my code and I am closing all files
            >explicitly after opening them.
            If you're running your program under Linux, a very easy way to confirm
            this is to look in the directory

            /proc/<pid>/fd

            where <pidis the PID of your running program. In here you will see a
            symlink to every file your program has open, the name of the link being
            the file descriptor number.

            To make it easier to watch, you may want to stick in a sleep of a few
            seconds in-between iterations of the code that executes the Python
            script.

            If you see the entries piling up in this directory, that will confirm
            that you're not closing those files.

            Comment

            Working...