my python3 threading prog didnt work with fifo-queue - multithreading

That's my code:
import threading
import queue
qq=queue.Queue(10)
def x11grab(n):
print('haha')
while True:
a='abcd'+str(n)
n+=1
qq.put(a)
print('put queue:',a)
def rtpsend():
while True:
s=qq.get()
head=s[:4]
body=s[4:]
print('head',head)
print('body',body)
t1=threading.Thread(target=x11grab,args=(1,))
t2=threading.Thread(target=rtpsend)
t1.start
t2.start
I wanna x11grab() function put string 'abcd1','abcd2'... into queue,and rtpsend() function get the string from queue, and display it. It's a demo, but it didn't work. I think your advice could be helpful.:-)

You never start your threads! change
t1.start
t2.start
to
t1.start()
t2.start()

Related

Multiprocessing processes don't start

When I try to make a process start, no matter what, it just fails to do so. This simple code doesn't work:
import multiprocessing
def function():
print("function started")
function_process = multiprocessing.Process(target = function)
function_process.start()
function_process.join()
The output of this code is simply nothing. If I print function_process after this, it returns <Process name='Process-1' pid=13432 parent=7564 stopped exitcode=0>. Adding if __name__ == "__main__" does nothing. Is there something I'm missing here?
Works for me:
$ python mp.py
function started
Maybe the code you show is part of a larger program, and this code is never called?
This is the code:
import multiprocessing
def function():
print("function started")
function_process = multiprocessing.Process(target = function)
function_process.start()
function_process.join()
Some IDEs redirect STDIN, STDERR and STDOUT, and data gets lost. The problem does not happen with Visual Studio Code or PyCharm.

How to terminate thread by given name

I founded a nice package that is called kthread which simplify the threading in python. I have also found out that it is possible to name give a thread by its name etc:
import sys
import time
import kthread
def func():
try:
while True:
time.sleep(0.2)
finally:
sys.stdout.write("Greetings from Vice City!\n")
sys.stdout.flush()
t = kthread.KThread(target=func, name="KillableThread1")
t.start()
t.is_alive()
t.terminate()
t.is_alive()
Instead of doing t.terminate() I wonder if there is a possibility to remove a thread by given name?
The following piece of code might help.
thread_dict = {}
t1 = kthread.KThread(target=func, name="KillableThread1")
t2 = kthread.KThread(target=func, name="KillableThread2")
thread_dict[t1.name] = t1
thread_dict[t2.name] = t2
After that when you want to kill a thread then do the following:
thread_dict["KillableThread1"].terminate()

Multithreading in Python within a for loop

Let's say I have a program in Python which looks like this:
import time
def send_message_realtime(s):
print("Real Time: ", s)
def send_message_delay(s):
time.sleep(5)
print("Delayed Message ", s)
for i in range(10):
send_message_realtime(str(i))
time.sleep(1)
send_message_delay(str(i))
What I am trying to do here is some sort of multithreading, so that the contents of my main for loop continues to execute without having to wait for the delay caused by time.sleep(5) in the delayed function.
Ideally, the piece of code that I am working upon looks something like below. I get a message from some API endpoint which I want to send to a particular telegram channel in real-time(paid subscribers), but I also want to send it to another channel by delaying it exactly 10 minutes or 600 seconds since they're free members. The problem I am facing is, I want to keep sending the message in real-time to my paid subscribers and kind of create a new thread/process for the delayed message which runs independently of the main while loop.
def send_message_realtime(my_realtime_message):
telegram.send(my_realtime_message)
def send_message_delayed(my_realtime_message):
time.sleep(600)
telegram.send(my_realtime_message)
while True:
my_realtime_message = api.get()
send_message_realtime(my_realtime_message)
send_message_delayed(my_realtime_message)
I think something like ThreadPoolExecutor does what you are look for:
import time
from concurrent.futures.thread import ThreadPoolExecutor
def send_message_realtime(s):
print("Real Time: ", s)
def send_message_delay(s):
time.sleep(5)
print("Delayed Message ", s)
def work_to_do(i):
send_message_realtime(str(i))
time.sleep(1)
send_message_delay(str(i))
with ThreadPoolExecutor(max_workers=4) as executor:
for i in range(10):
executor.submit(work_to_do, i)
The max_workers would be the number of parallel messages that could have at a given moment in time.
Instead of a multithread solution, you can also use a multiprocessing solution, for instance
from multiprocessing import Pool
...
with Pool(4) as p:
print(p.map(work_to_do, range(10)))

test pyautogui functions with unittest in python3.6

I need to test functions that use pyautogui. For example, if pressing keyboard key "a" actually press an "a". How can I reproduce this? There is a way to capture the key that it´s been press?
Ideal if it works in Windows and Linux
The PyAutoGUI unit tests have something like this. See the TypewriteThread code for details. Set up a thread to wait a second and call pyautogui.typewrite(), then call input() to accept text. Make sure your window is in focus and the typewrite() thread ends by pressing Enter (the \n character).
import time
import threading
import pyautogui
class TypewriteThread(threading.Thread):
def __init__(self, msg, interval=0.0):
super(TypewriteThread, self).__init__()
self.msg = msg
self.interval = interval
def run(self):
time.sleep(0.25)
pyautogui.typewrite(self.msg, self.interval)
t = TypewriteThread('Hello world!\n')
t.start()
response = input()
print(response == 'Hello world!')

hourly action resetter with threading

this is some code I have written based off basic knowledge of threading I acquired. What I am trying to do is limit the actions hourly so it doesn't spam.
import datetime
import time
from threading import Thread
the_Minute = str(datetime.datetime.now().time())[3:5]
action_Limit = 0
def updater():
global the_Minute
while True:
the_Minute=str(datetime.datetime.now().time())[3:5]
#updates the minute value
def resetter():
global action_Limit
global the_Minute
while True:
if the_Minute=='00':
action_Limit=0
time.sleep(30)
def performer():
global action_Limit
global the_Minute
while the_Minute!='00' and action_Limit<100:
#perform actions here
action_Limit+=1
print(action_Limit)
time.sleep(1)
updater_Thread = Thread(target=updater)
resetter_Thread = Thread(target=resetter)
performer_Thread = Thread(target=performer)
updater_Thread.start
performer_Thread.start
resetter_Thread.start
When I run this, nothing happens, but I also don't receive any errors. Could anyone tell me how I could make it work, or point me to some resources to help? Thank you for your time.

Resources