Have a thread constantly run in background python - python

I have a function to check for sniffing tools I want to constantly run in the background of my python script:
def check():
unwanted_programmes = [] # to be added to
for p in psutil.process_iter(attrs=['pid', 'name']):
for item in unwanted_programmes:
if item in str(p.info['name']).lower():
webhook_hackers(str(p.info['name'])) # send the programme to a webhook which is in another function
sys.exit()
time.sleep(1)
I want this to run right from the start and then the rest of the script
I have written code like so:
if __name__ == "__main__":
check = threading.Thread(target=get_hackers())
check.start()
check.join()
threading.Thread(target=startup).start()
# startup function just does some prints and inputs before running other functions
However, this code only runs check once and then startup but I want check to run and then keep running in the background. Meanwhile, startup to run just once, how would I do this?

Your check function does what you want it to, but it only does it once, and that's the behavior that you're seeing; the thread finishes running the function and then cleanly exits. If you place everything in the function inside of a while(True): block at the top of the function then the function will loop infinitely and the thread will never exit, which sounds like it's what you want.

Related

Python : call a function and wait for its thread(s) to finish

I am using Python to script a gdb session. My goal is to run a function whenever a breakpoint is hit, using gdb.events.stop.connect.
Here is my code in essence, which I call from gdb by running source main.py :
RESULT = None
def breakpoint_handler(event):
global RESULT
RESULT = do_something(event) # boolean
sleep(1)
def main():
global RESULT
gdb.events.stop.connect(breakpoint_handler)
command = "some gdb command"
gdb.execute(command)
sleep(1)
if RESULT:
# do something
pass
else:
# something else
pass
main()
This code works, but only thanks to the sleep calls, that tries to make sure the gdb.execute(command)call actually finish executing the gdb command before continuing. There is only little documentation but my guess is that this function is threaded, which explains the effectiveness of the waitas a fix.
Is there a way to make this cleaner by waiting for the thread created by gdb.execute to finish processing, without having access to the body of this method ?
You can set an event inside your callback and wait for it in your main thread. Here is an example, with the callback being called after 5 seconds by timer:
import threading
def some_callback():
event.set()
event = threading.Event()
threading.Timer(5, some_callback).start()
event.wait()

How to continue with the main program when threading

I'm trying to run a thread in python and am fairly new at it. While going through the basics, when I start a thread, the program doesn't continue with the main program and is stuck in the thread. i.e. it prints only "hello world" and never prints "hi there".
from threading import Thread
import time
def hello_world():
while True:
print("hello world")
time.sleep(5)
t = Thread(target = hello_world())
t.start()
print("hi there")
I'm using spyder IDE.
I searched online for some basic programs in threading but for those, the code works.
How should I proceed?
Your problem is in the line t = Thread(target = hello_world()).
You are trying to create a Thread with the target argument. According to the order of evaluation, Python first needs to know what to assign to target, so it evaluates the RHS. In your case the RHS is hello_world(). So the function is already being called in that exact moment!
So the function executes and enters the infinite loop and the Thread is never even created and your program is stuck.
What you would want to do is pass to target a mere reference to the function, so change said line to:
t = Thread(target = hello_world)
And now the RHS is evaluated as a reference to the given function, and behind the scenes the Thread will be created, making the call to that function, and your main Thread will keep running as expected.

Python: I start a new thread, and my program pauses until the thread is finished

When I try to start a new thread, my entire program stops until the thread's function finishes. I am trying to make the thread start and continue while my program runs at the same time.
Code:
def do_python(string):
while True:
exec(string, globals())
time.sleep(0.1)
getKeyThread = threading.Thread(target=do_python("key = cpc.get_key()"), daemon=True).start()
time.sleep(0.2)
while True:
if key == 9:
print("Tab pressed.")
exit()
I have imported all of the required modules, so that is not the problem. Any functions used in here that aren't defined have been defined elsewhere and work perfectly fine. I haven't included my entire program here, because it is far too big to paste here.
By doing
do_python("key = cpc.get_key()")
you are actually calling, in your main thread, the do_python function (which has an infinite loop and will never stop running). Since the function never returns anything, it will just keep running forever. If it did return something, you'd probably get an error unless whatever is returned in a callable object.
The argument target requires a callable, so you have to pass your function to it
getKeyThread = threading.Thread(target=do_python, args=some_args, daemon=True).start()

Restart a python script from backround_thread

I've been spending some time in searching for the correct code but I got no luck.
I have below python script with background thread and a main prog.. I want to restart the script once the background thread encounters a condition. Hope you can help me with this. TIA
With this script, both background_stuff and "main" are running at the same time.
def background_stuff():
while True:
if condition == 'True':
### restart the script
t = Thread(target=background_stuff)
t.start()
### main
if __name__ == '__main__':
while True:
#do something
Can you restructure your script like so?
def main():
t = Thread(target=background_stuff)
t.start()
while True:
#do something
def background_stuff():
while True:
if condition == 'True':
### restart the script
#t = Thread(target=background_stuff)
#t.start()
### main
if __name__ == '__main__':
main()
Calling main now should create a new thread that will run the background stuff and the script basically restarts. The only issue is that state is not reset. If you need to reset state then you could actually run your script from scratch from within your script using:
os.system("yourScript.py -yourargs")
I don't think this is best practice though...
Regardless of which solution you end up using, you still need to terminate the old main loop. This could either be done by setting some flag when you "restart your script" and then have the main loop periodically check for that flag and do a controlled shut down once the flag is set, or you can run the main loop in another thread which you can access globally or from the other thread and then terminate it. Just remember that forcibly shutting down a thread is often not adviced.

Python: run one function until another function finishes

I have two functions, draw_ascii_spinner and findCluster(companyid).
I would like to:
Run findCluster(companyid) in the backround and while its processing....
Run draw_ascii_spinner until findCluster(companyid) finishes
How do I begin to try to solve for this (Python 2.7)?
Use threads:
import threading, time
def wrapper(func, args, res):
res.append(func(*args))
res = []
t = threading.Thread(target=wrapper, args=(findcluster, (companyid,), res))
t.start()
while t.is_alive():
# print next iteration of ASCII spinner
t.join(0.2)
print res[0]
You can use multiprocessing. Or, if findCluster(companyid) has sensible stopping points, you can turn it into a generator along with draw_ascii_spinner, to do something like this:
for tick in findCluster(companyid):
ascii_spinner.next()
Generally, you will use Threads. Here is a simplistic approach which assumes, that there are only two threads: 1) the main thread executing a task, 2) the spinner thread:
#!/usr/bin/env python
import time
import thread
def spinner():
while True:
print '.'
time.sleep(1)
def task():
time.sleep(5)
if __name__ == '__main__':
thread.start_new_thread(spinner, ())
# as soon as task finishes (and so the program)
# spinner will be gone as well
task()
This can be done with threads. FindCluster runs in a separate thread and when done, it can simply signal another thread that is polling for a reply.
You'll want to do some research on threading, the general form is going to be this
Create a new thread for findCluster and create some way for the program to know the method is running - simplest in Python is just a global boolean
Run draw_ascii_spinner in a while loop conditioned on whether it is still running, you'll probably want to have this thread sleep for a short period of time between iterations
Here's a short tutorial in Python - http://linuxgazette.net/107/pai.html
Run findCluster() in a thread (the Threading module makes this very easy), and then draw_ascii_spinner until some condition is met.
Instead of using sleep() to set the pace of the spinner, you can wait on the thread's wait() with a timeout.
It is possible to have a working example? I am new in Python. I have 6 tasks to run in one python program. These 6 tasks should work in coordinations, meaning that one should start when another finishes. I saw the answers , but I couldn't adopted the codes you shared to my program.
I used "time.sleep" but I know that it is not good because I cannot know how much time it takes each time.
# Sending commands
for i in range(0,len(cmdList)): # port Sending commands
cmd = cmdList[i]
cmdFull = convert(cmd)
port.write(cmd.encode('ascii'))
# s = port.read(10)
print(cmd)
# Terminate the command + close serial port
port.write(cmdFull.encode('ascii'))
print('Termination')
port.close()
# time.sleep(1*60)

Categories

Resources