Reputation: 35
I was just wandering how to print text while waiting for the users input. Like for example if we were in a chat app, we have an input()
so that the user could send messages and print()
when receiving messages. It needs to be simultaneous. I tried to use threads but it always stops at a thread.
Example:
def receive(client):
threadName = client.getThreadName()
while not client.isStopThread():
time.sleep(1)
print('test')
while (client.isThereMessage()):
print('[' + threadName + ']: ' + client.getMessage())
and for the main program
client.startThread(thread.uid)
receiveThread = Thread(target = receive(client))
receiveThread.deamon = True
receiveThread.start()
while True:
toSendMessage = input('[' + client.fetchThreadInfo(client.uid)[client.uid].name + ']: ')
client.sendMessage(toSendMessage, thread_id=thread.uid, thread_type=thread.type)
Upvotes: 2
Views: 2564
Reputation: 6430
You're calling the Thread
class constructor incorrectly. The signature is:
threading.Thread(target=None, args=(), kwargs={})
The target
is the function object itself, i.e., receive
, not receive(client)
. You're now calling the receive
function with client
as the input, and then passing the return value of that function (which appears to be None
) as the target
keyword-argument to the Thread
constructor. If the receive
function loops indefinitely, then the code will definitely stall in the Thread
constructor.
You should instead call the Thread
constructor like so:
receiveThread = Thread(target=receive, args=(client,))
Also, in general, you don't need threading to both print something and wait for input. You can instead do what is called synchronous I/O multiplexing, which means performing I/O on multiple objects at the same time, but from a single thread. The idea is to wait for notification from the OS when one or more objects are available for either writing or reading (or both). Look at the select
or selectors
modules for more information.
Here is a simple example. It just waits for up to one second for input from the user. If input is received, it just echos it back, and if none is received, it prints Nothing new
.
import sys
import select
timeout = 1.0
while True:
rlist, _ = select.select([sys.stdin], [], [], timeout)
if len(rlist):
print(sys.stdin.readline())
else:
print('Nothing new')
You could adapt this to wait for both user input and for a new message that you want to print to the user's console.
Upvotes: 1