python - Is it possible to get another thread's print content? - TagMerge
3Is it possible to get another thread's print content?Is it possible to get another thread's print content?

Is it possible to get another thread's print content?

Asked 1 years ago
0
3 answers

I present at the end a way for doing what is requested but I do not recommend using bare prints for this. There are better tools, and if you still want to stick with print, you can use the file keyword to specify where the output should go.

import time
import sys 

def get(out_stream=sys.stdout):
    for i in range(100):
        print(i, file=out_stream)
        print("\n")
        time.sleep(1)

you can pass a file object opened with open as the argument, and the output will go to that file. Alternatively, you can use a io.StringIO as @barmar suggested, and write the contents to a file once get finishes.

All other options mess with sys.stdout, that is the default file object that print uses (it is the default value of the file keyword argument). This affects everything that uses sys.stdout, which can be more than all the print statements that get executed.

If you need to redirect bare print statements (not using print's file keyword), you must replace sys.stdout. The most obvious replacement would be to use an output file object:

from threading import Thread
import time
import sys

def get():
    for i in range(100):
        print(i)
        time.sleep(1)


if __name__ == "__main__":
    old_stdout = sys.stdout
    with open("output.txt", "a") as text_fil:
        sys.stdout = text_fil
        get_thread = Thread(None, get)
        get_thread.start()
        get_thread.join()
    sys.stdout = old_stdout

If you need to have one writing thread and a reading thread, exactly as the question states, you can use Queues, but a simpler approach uses pipes (I added a dummy thread (postthread) that calls post to make it similar to OP's use):

from threading import Thread
import time
import sys
import os

def get():
    for i in range(100):
        print(i)
        time.sleep(1)

def post(read_pipe):
    with open("output.txt", "ab") as text_fil:  # os.read yields bytes
        try:
            data = os.read(read_pipe, 65535)  # arbitrary (but large) number
            text_fil.write(data)
        except Exception as e:
            return True  # the read descriptor was closed: quit
    return len(data) == 0  # the write descriptor was closed: quit

def postthread(read_pipe):
    for _ in range(21):
        time.sleep(5)
        if post(read_pipe):
            return

if __name__ == "__main__":
    old_stdout = sys.stdout
    r_fd, w_fd = os.pipe()
    with os.fdopen(w_fd, 'wt') as write_pipe: # write pipe is a file object
        read_pipe = r_fd
        sys.stdout = write_pipe
        get_thread = Thread(None, get)
        post_thread = Thread(None, postthread, args=(read_pipe, ))
        post_thread.start()
        get_thread.start()
        get_thread.join()
        sys.stdout = old_stdout
        # closing the write pipe (and its file descriptor) causes read to see EOF.
    post_thread.join()
    os.close(r_fd)
    sys.stdout = old_stdout

Source: link

0

mydata = threading.local()
mydata.x = 1
# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()
# Consume an item
with cv:
    cv.wait_for(an_item_is_available)
    get_an_available_item()
while not predicate():
    cv.wait()
maxconnections = 5
# ...
pool_sema = BoundedSemaphore(value=maxconnections)

Source: link

0

Consider the following example:
class Foo
{
  int _answer;
  bool _complete;
 
  void A()
  {
    _answer = 123;
    _complete = true;
  }
 
  void B()
  {
    if (_complete) Console.WriteLine (_answer);
  }
}
The simplest kind of memory barrier is a full memory barrier (full fence) which prevents any kind of instruction reordering or caching around that fence. Calling Thread.MemoryBarrier generates a full fence; we can fix our example by applying four full fences as follows:
class Foo
{
  int _answer;
  bool _complete;
 
  void A()
  {
    _answer = 123;
    Thread.MemoryBarrier();    // Barrier 1
    _complete = true;
    Thread.MemoryBarrier();    // Barrier 2
  }
 
  void B()
  {
    Thread.MemoryBarrier();    // Barrier 3
    if (_complete)
    {
      Thread.MemoryBarrier();       // Barrier 4
      Console.WriteLine (_answer);
    }
  }
}
By virtue of that last point, the following is thread-safe:
int x = 0;
Task t = Task.Factory.StartNew (() => x++);
t.Wait();
Console.WriteLine (x);    // 1
You don’t necessarily need a full fence with every individual read or write. If we had three answer fields, our example would still need only four fences:
class Foo
{
  int _answer1, _answer2, _answer3;
  bool _complete;
 
  void A()
  {
    _answer1 = 1; _answer2 = 2; _answer3 = 3;
    Thread.MemoryBarrier();
    _complete = true;
    Thread.MemoryBarrier();
  }
 
  void B()
  {
    Thread.MemoryBarrier();
    if (_complete)
    {
      Thread.MemoryBarrier();
      Console.WriteLine (_answer1 + _answer2 + _answer3);
    }
  }
}
Working with shared writable fields without locks or fences is asking for trouble. There’s a lot of misleading information on this topic — including the MSDN documentation which states that MemoryBarrier is required only on multiprocessor systems with weak memory ordering, such as a system employing multiple Itanium processors. We can demonstrate that memory barriers are important on ordinary Intel Core-2 and Pentium processors with the following short program. You’ll need to run it with optimizations enabled and without a debugger (in Visual Studio, select Release Mode in the solution’s configuration manager, and then start without debugging):
static void Main()
{
  bool complete = false; 
  var t = new Thread (() =>
  {
    bool toggle = false;
    while (!complete) toggle = !toggle;
  });
  t.Start();
  Thread.Sleep (1000);
  complete = true;
  t.Join();        // Blocks indefinitely
}

Source: link

Recent Questions on python

    Programming Languages