VoodooChild92
VoodooChild92

Reputation: 2053

Redirect a thread's output to a string in python

def findStats():
     thread1 = thread.start_new_thread(func1, (arg_1, arg_2))
     thread2 = thread.start_new_thread(func2, (arg_3, arg_4))

def func1(arg_1, arg_2):
     """
        Some code which prints some stuff
     """

def func2(arg_3, arg_4):
     """ 
        Some code which prints some other stuff
     """

Here, what I want to do is to capture the printed output from func1 and func2 in two seperate strings so that I can use in to show them in two different tabs in my GUI.

Also, I tried using the StringIO() but as they're parallel running threads, the output sequence is obviously messed up. I'm learning about subprocess thing to use but not sure how.. Still trying on it.

Can it be done? If so, please show me a way. Thanks in advance :)

Upvotes: 0

Views: 5058

Answers (3)

alexis
alexis

Reputation: 50200

I tried using the StringIO() but as they're parallel running threads, the output sequence is obviously messed up.

Since you have this method working, you can stick with it: Redirect sys.stdout to a separate StringIO object for each thread. Redirect once before creating the first thread; then redirect to a different StringIO object before creating the second thread. Your function findStats can do all this, and should return the two string buffers as a tuple.

Upvotes: 0

VoodooChild92
VoodooChild92

Reputation: 2053

  import sys
  from cStringIO import StringIO
  from multiprocessing import Process, Queue

  def mp():
      queue = Queue()
      p = Process(target=loop,args=('lo','op'))
      q = Process(target=doop,args=('do','op'))
      p.start()
      q.start()
      p.join()
      q.join()

  def loop(p,x):
      old_stdout = sys.stdout  # Redirection of the printing output to a StringIO
      sys.stdout = mystdout = StringIO()
      for i in xrange(100):
          print p + x
      ### Write the code\functions necessary in here. ###
      sys.stdout = old_stdout
      dataStats_1 = mystdout.getvalue()    # Put all the redirected output into a string.

  def doop(q,y):
      old_stdout = sys.stdout   # Redirection of the printing output to a StringIO() 
      sys.stdout = mystdout = StringIO()
      for i in xrange(100):
          print q+y
      ### Write the code\functions necessary in here. ###
      sys.stdout = old_stdout
      dataStats_2 = mystdout.getvalue()                      

  if __name__ == "__main__":
      mp()

So, in each of the dataStats_1 and dataStats_2 variables contain the printed output from the function 'doop' and 'loop'.

I don't know how authentic this above method. But this actually works for me.

Also, this method of redirection of the printing output to a StringIO won't work if you try to use a thread instead of a Process because a thread inherits the parent's I/O source and when you change it in a particular thread, it changes for the parent thread too. But for a child process, it doesn't interfere with the parent's I/O sources. So, this works.

Upvotes: 0

Vinayak Kolagi
Vinayak Kolagi

Reputation: 1881

Use logging module of python. This handles the serialization of access and you can set level for each log. Time stamping the message may be required with log identifier.

Link here http://docs.python.org/howto/logging.html

Upvotes: 1

Related Questions