Python Thread counter - python

I'm trying to make thread counter but I'm stuck. I've got the code below:
import threading
def Hello():
global t
print("Hello!")
t = threading.Timer(1, Hello)
t.start()
Hello()
How can I make the loop stop say after 5 'Hellos'?

Not sure what you're trying to accomplish but this code will work
import threading
count = 0
def hello():
global count
print("Hello!")
count += 1
if count < 5:
t = threading.Timer(1, function=hello,)
t.start()
hello()

Related

How can I increment a variable inside a function without using global variable please?

I need a way to print a timer every second and execute an action every 10 seconds.
The output of the program should be like below.
Timer is 1
Timer is 2
Timer is 3
Timer is 4
Timer is 5
Timer is 6
Timer is 7
Timer is 8
Timer is 9
Timer is 10
Action is executed
Timer is 1
Timer is 2
Timer is 3
Timer is 4
Timer is 5
Timer is 6
Timer is 7
Timer is 8
Timer is 9
Timer is 10
Action is executed
Timer is 1
Timer is 2
Timer is 3
.
.
.
The program should use threading. It should not be an infinite while loop.
I could have done it with below code but it uses a global variable. How can I do it without using a global variable and with a small amount of code like below.
import threading
import time
global MytTimer
MytTimer=0
def foo():
global MytTimer
MytTimer=MytTimer+1
print("Timer is " + str(MytTimer))
threading.Timer(1, foo).start()
if MytTimer >= 10:
MytTimer=0
print("Action is executed")
foo()
I did it by creating a class.
import threading
import time
class count():
def __init__(self, MytTimer):
self.MytTimer = MytTimer
self._run()
def _run(self):
threading.Timer(1, self._run).start()
self.MytTimer += 1
print("Timer is " + str(self.MytTimer))
if self.MytTimer >= 10:
self.MytTimer=0
print("Action is executed")
a=count(MytTimer = 0)
You could create a ticker thread that delivers values 1-10 to a queue, and then a consumer that executes an action whenever the value read from the queue is 10:
import threading
import time
import queue
def foo():
q = queue.Queue()
def ticker():
while True:
for i in range(1,11):
print(f'Timer is {i}')
q.put(i)
time.sleep(1)
t_ticker = threading.Thread(target=ticker)
t_ticker.start()
while True:
i = q.get()
if i == 10:
print("Action is executed")
foo()

Print message while a function is running in Python with AsyncIO

I'm trying to create a print function that keeps printing, for example, 'Hello World', while another function (called miner) is running in parallel, and both functions must end at the same time.
This is for a real-time cost measurer for bitcoin mining that I'm working on.
I found that python as asyncio and tried to use it, however I couldn't get the print function to stop at the same time the miner function ends. The timer function printed once and waited for the miner function.
import asyncio
import time
from datetime import datetime
class Test2:
async def miner(self):
await asyncio.sleep(5)
return 0
async def timer(self):
while True:
print("\n Hello World \n")
time.sleep(1)
t2 = Test2()
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(t2.miner(), t2.timer()))
I tried concurrent tasks, but both function does not run in parallel (timer and miner).
Could you show me a way to solve this?
Thank you!
time.sleep() is not asynchronous function so timer process locks other operations before it ends (but unfortunately it is endless)
You may add shared trigger variable to stop timer when miner complete
import asyncio
class Test2:
is_ended = False
async def miner(self):
await asyncio.sleep(5)
self.is_ended = True
print("\n I'm done \n")
return 0
async def timer(self):
while True:
if self.is_ended:
print('\n Bye Bye \n')
break
print("\n Hello World \n")
await asyncio.sleep(1)
t2 = Test2()
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(t2.miner(), t2.timer()))
Hello World
Hello World
Hello World
Hello World
Hello World
I'm done
Bye Bye
You can also use threading:-
def func1():
print('Working')
def func2():
print("Working")
if __name__ == '__main__':
Thread(target = func1).start()
Thread(target = func2).start()
You can use multiprocessing or threading
from multiprocessing import Process
index=0
def func1():
global index
print ('start func1')
while index< 20:
index+= 1
print ('end func1')
def func2():
global rocket
print ('start func2')
while index< 10:
index+= 1
print ('end func2')
if __name__=='__main__':
p1 = Process(target = func1)
p1.start()
p2 = Process(target = func2)
p2.start()
for treading
import threading
x = threading.Thread(target=func1)
y = threading.Thread(target=func1)

How to cancel a setInterval in python?

I am using this code to call a function doSomething every 3 seconds. but I want that when numeroPeticiones== 3, stop doing it. I have looked for many examples, but none works. In my case, my function continues to be executed eternally, even though the condition of numeroPeticiones== 3 is fulfilled. how can I solve that?
import threading
from threading import Timer
numeroPeticiones=0
def doSomething():
global numeroPeticiones
numeroPeticiones=numeroPeticiones+1
print ("hello, world",numeroPeticiones)
if numeroPeticiones == 3:
print("cancel")
t.cancel()
def set_interval(func, sec):
def func_wrapper():
set_interval(func, sec)
func()
t = threading.Timer(sec, func_wrapper)
t.start()
return t
You can do the following, if num is equal to the 3, it wont start the timer
from threading import Timer
num = 0
def hello():
global num
num += 1
print("hello, world")
if (num < 3):
Timer(3, hello).start()
Timer(3, hello).start()

Cancel timer in Python

I am working on timer class in python and wrote a simple test code for the same. My purpose is to print the "hello world" message 10 times and then cancel the timer once the iterations are done. The problem is I am unable to cancel the timer and code seems to print "hello world" infinitely.
Below is my code:
from threading import Timer
class myclass():
iteration_count = 0
heartbeat = 1
def printMsg(self):
print "hello world!"
def start_job(self):
self.printMsg()
self.iteration_count = self.iteration_count + 1
if self.iteration_count == 10:
Timer(self.heartbeat, self.start_job, ()).cancel()
Timer(self.heartbeat, self.start_job, ()).start()
m = myclass()
m.start_job()
I am using Python 2.7
Any help would be highly appreciated
Your problem is you've made another Timer() in if condition and .cancel() it. The following code solves your problem:
from threading import Timer
class MyClass(object):
def __init__(self):
self.iteration_count = 0
self.heartbeat = 1
#staticmethod
def print_msg():
print "hello world!"
def start_job(self):
self.print_msg()
self.iteration_count += 1
timer = Timer(
interval=self.heartbeat,
function=self.start_job,
)
timer.start()
if self.iteration_count >= 10:
timer.cancel()
MyClass().start_job()
Seems like you start your timer again right after you cancelled it.
If you change your code to return from start_job() when your end-condition is reached it should work.
if self.iteration_count == 10:
Timer(self.heartbeat, self.start_job, ()).cancel()
return
Actually you don't even have to cancel the timer this way, you just don't start a new one, if the condition is reached.
cancelmethod is used to stop the created timer before its action has begun, so just return will be ok.
if self.iteration_count == 10:
return
See Timer Objects
The timer can be stopped (before its action has begun) by calling the cancel() method.
def hello():
print "hello, world"
t = Timer(30.0, hello)
t.start() # will print "hello, world" after 30 seconds
t.cancel() # stop it printing "hello, world"

Python threading. How do I lock a thread?

I'm trying to understand the basics of threading and concurrency. I want a simple case where two threads repeatedly try to access one shared resource.
The code:
import threading
class Thread(threading.Thread):
def __init__(self, t, *args):
threading.Thread.__init__(self, target=t, args=args)
self.start()
count = 0
lock = threading.Lock()
def increment():
global count
lock.acquire()
try:
count += 1
finally:
lock.release()
def bye():
while True:
increment()
def hello_there():
while True:
increment()
def main():
hello = Thread(hello_there)
goodbye = Thread(bye)
while True:
print count
if __name__ == '__main__':
main()
So, I have two threads, both trying to increment the counter. I thought that if thread 'A' called increment(), the lock would be established, preventing 'B' from accessing until 'A' has released.
Running the makes it clear that this is not the case. You get all of the random data race-ish increments.
How exactly is the lock object used?
Additionally, I've tried putting the locks inside of the thread functions, but still no luck.
You can see that your locks are pretty much working as you are using them, if you slow down the process and make them block a bit more. You had the right idea, where you surround critical pieces of code with the lock. Here is a small adjustment to your example to show you how each waits on the other to release the lock.
import threading
import time
import inspect
class Thread(threading.Thread):
def __init__(self, t, *args):
threading.Thread.__init__(self, target=t, args=args)
self.start()
count = 0
lock = threading.Lock()
def incre():
global count
caller = inspect.getouterframes(inspect.currentframe())[1][3]
print "Inside %s()" % caller
print "Acquiring lock"
with lock:
print "Lock Acquired"
count += 1
time.sleep(2)
def bye():
while count < 5:
incre()
def hello_there():
while count < 5:
incre()
def main():
hello = Thread(hello_there)
goodbye = Thread(bye)
if __name__ == '__main__':
main()
Sample output:
...
Inside hello_there()
Acquiring lock
Lock Acquired
Inside bye()
Acquiring lock
Lock Acquired
...
import threading
# global variable x
x = 0
def increment():
"""
function to increment global variable x
"""
global x
x += 1
def thread_task():
"""
task for thread
calls increment function 100000 times.
"""
for _ in range(100000):
increment()
def main_task():
global x
# setting global variable x as 0
x = 0
# creating threads
t1 = threading.Thread(target=thread_task)
t2 = threading.Thread(target=thread_task)
# start threads
t1.start()
t2.start()
# wait until threads finish their job
t1.join()
t2.join()
if __name__ == "__main__":
for i in range(10):
main_task()
print("Iteration {0}: x = {1}".format(i,x))

Categories

Resources