How to continue a code while a loop is already running - python

I created a code that shows a real time clock at the beginning (works by a loop and refreshing itself in every 1 sec using \r )
But I want to run the rest of the code while the clock is ticking (continuously). But this isn't going any further while the loop is running.
I think there is no need to write the code of the clock.

If you want to have a task running, while using another you can use multi-threading. This means you tell your processor two different tasks and it will be continued as long as you tell it to work. See here a post about multithreading and multiprocessing. You can use the thread function of python for this.
Here a small example:
import threading
import time
# Define a function for the thread
def print_time( threadName, delay):
count = 0
while count < 10:
time.sleep(delay)
count += 1
print ("%s: %s" % ( threadName, time.ctime(time.time()) ))
def counter(threadName, number_of_counts, delay):
count=0
while count < number_of_counts:
print ("%s: %s" % ( threadName, count))
time.sleep(delay)
count +=1
# Create two threads as follows
threading.Thread(target=print_time, args=("Thread-1", 1, )).start()
threading.Thread(target=counter, args=("Thread-2", 100, 0.1,)).start()
for further information check the documentation. Note that thread has been renamed to _thread in python 3

Related

How to use Timer Thread with Python

I am writing a Ryu application(Python) in which I have if else statement. If a condition satisfies for the first time, then it should start the timer till 10 seconds, within these 10 seconds there will be other packets arriving as well matching the same condition but I don't want to start timer every time a condition is satisfied(within these 10 seconds). In short, the timer should run in parallel.
Here is the code snippet I used for thread.
Every time I run this and send multiple packets then multiple threads start whereas I want only one thread to run till 10 seconds
def timeit():
time.sleep(10)
aggr()
return
def aggr():
self.no_of_data=len(self.iot_data)
self.ip_proto=proto
self.ip_saddr=source
self.ip_daddr=destination
ip_head= pack('!BBHHHBBH16s16s' , self.ip_ihl_ver, self.ip_tos, self.ip_tot_len, self.ip_id, self.ip_frag_off, self.ip_ttl,self.ip_check,self.ip_proto, self.ip_saddr, self.ip_daddr)
total_pkts= pack('!I', self.no_of_data)
print "TOTALLLL,,,,",self.no_of_data
ip_head="{" + ip_head + "}"
total_pkts="{" + total_pkts + "}"
s='$'
data = s.join(self.iot_data)
data="$" + data
pckt= ip_head + total_pkts + data
self.iot_data = []
print "BUFFER: ", self.iot_data
self.iot_data_size = 0
self.start_time = time.time()
self.logger.info("packet-out %s" % (repr(pckt),))
out_port = ofproto.OFPP_FLOOD
actions = [parser.OFPActionOutput(out_port)]
out = parser.OFPPacketOut(datapath=datapath,
buffer_id=ofproto.OFP_NO_BUFFER,
in_port=in_port, actions=actions,
data=pckt)
print "out--->" , out
datapath.send_msg(out)
thread1 = threading.Thread(target=timeit)
thread1.start()
if proto == 150 and total_len < 1500:
if not thread1.isAlive():
thread1.run()
print "ifff"
data = msg.data
#print " # stores the packet data"
self.iot_data.append(data)
#print "# increment size counter"
self.iot_data_size += total_len
#elapsed_time = time.time() - self.start_time
print "ELAPSED: ", elapsed_time
print "BUFFER: ", self.iot_data
After 10 seconds, again timer should start when the first packet arrives and it should run parallel with the same code.
I am so much confused with this. Please anyone help.
I hope this is clear if not I am sorry please ask for the clarification.
Thank you
Indeed, you have to go with multi-threading (might be achieved without it but it would certainly be a pain in the ass). The idea is to run a thread that will run a function that sleeps for 10 seconds and returns. After this function returns, the thread will be set as inactive, until we run it the next time.
By knowing that we can write the following code. All details and explanations are written as comments for easier reference.
import time
import threading
packet_groups = [] # Groups of packets inside 10 seconds.
group = [] # Temporary group that will get stored into packet_groups.
# The function that will count 10 seconds:
def timeit():
sleep(10)
return
# Do something with packets.
def packet_handler():
...
# Put all your code inside another function that does not create
# new thread each time. Create a thread in main and then run this function.
def get_packets(thread1):
... # get packets
if dst == 'some_address':
# Check if thread is alive. If it is alive, a counter is running.
# If it is not alive, then we must start the counter by running
# thread.
if not thread1.isAlive():
thread1.run()
packet_handler(packet, True)
else:
packet_handler(packet, False)
if __name__ == '__main__':
# Create thread.
thread1 = threading.Thread(target=timeit)
# Start the thread. This is done only once per each thread.
thread1.start()
get_packets(thread1)
Now since you mentioned that you want to group the packets inside these 10 seconds blocks, you can implement packet_handler() like this:
def packet_handler(packet, new):
# If we started new thread and the group isn't empty, we must
# append group to packet_groups (that is all groups) and reset
# the group to only contain current packet
if new and group != []:
packet_groups.append(group)
group = [packet]
return
# If group isn't new, we are still inside 10 seconds block. We
# just append the current packet to this block.
if not new:
group.append(packet)
If you want to be able to print or in any other way be able to show the timer, you can't sleep for 10 seconds because if you sleep for 10 seconds, nothing will be done in between. In such case you want to change timeit() to something like this:
def timeit():
for i in range(10):
print 'Time remaining: {0}s'.format(10-i)
sleep(1)
return

threading module. Not sure if I created multiple threads

I am trying to learn the "threading" module. However, I am not sure I was able to create multiple threads.
import threading
import time
def somefunction():
for loop in range (10):
print "thread sleeps for 20 seconds"
time.sleep(20)
print "thread %d woke up"
counter = 0
while counter < 10:
threader = threading.Thread(target=somefunction())
counter = counter +1
When I run the following command, it only returns one NLWP.
ps axo pid,ppid,rss,vsz,nlwp,cmd | grep -i python
What am I doing wrong?
You have to use the reference in the parameter target to somefunction and not call the function.
import threading
import time
def somefunction():
for loop in range (10):
print "thread sleeps for 20 seconds"
time.sleep(20)
print "thread %d woke up"
for counter in range(10):
threader = threading.Thread(target=somefunction)

Making a Queue for a function so it only runs once at a time in python

I have a multithreaded function, which all write to the same log file. How can I make this function (maybe with a function decorator) to add the execution of writing to the log file to a queue.
Small example:
#!/usr/bin/python
import thread
import time
# Define a function for the thread
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
writeToLog(threadName, time.ctime(time.time()))
print "%s: %s" % ( threadName, time.ctime(time.time()) )
# Create two threads as follows
try:
thread.start_new_thread( print_time, ("Thread-1", 2, ) )
thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
print "Error: unable to start thread"
def writeToLog(threadName, time):
self.fileWriter = open("log.txt", "w")
self.fileWriter.write("ThreadName: " + threadName + "\n")
self.fileWriter.write("Time: " + time + "\n")
self.fileWriter.close()
How can I make this function writeToLog add to a queue when executed? Now I get every time both threads call the writeToLog function an error because the other writeToLog function (from the other thread) already closed the file. When having a global variable for this writer, which is closed in the end, I get output like this:
ThreadName: thread1
ThreadName: thread2
Time: 9:50AM
Time: 9:50AM
And the output I always want has to look like this:
ThreadName: Thread-1
Time: 9:50AM
ThreadName: Thread-2
Time: 9:50AM
Concurrency access to a shared resource is a well known problem. Python thread provide some mechanism to avoid issues.
Use python locks : http://docs.python.org/2/library/threading.html#lock-objects
Lock are used to synchronize access to a shared resource :
lock = Lock()
lock.acquire() # will block if lock is already held
... access shared resource
lock.release()
More information : http://effbot.org/zone/thread-synchronization.htm
Search for "Python synchronization"

how to print this number in a shortest time using thread in python

this is my code :
import thread
k=0
b=0
def a(n):
i = 0
while i<n:
print i
i += 1
j = 5000
while k < 5000:
a(k)
k+=1
for n in range(2,5):
thread.start_new_thread(a,(j*n,))
and i want to Run three threads and a main thread,
the main thread print 1,2,3,4,5,....5000
and the thread1 print 5001,5002,5003,...10000
the thread2 print 10001,10002,10003,...15000
the thread3 print 15001,15002,15003,...20000
they are at the same time
so what can i do ,
thanks
You should use threading instead of thread, since it's easier to implement and it works in almost every case. Now your code will be like:
import threading
class PrintNumber(Thread):
def __init__(self, n):
self.n = n
def run(self):
for i in range(n, n+5000):
print i
# create your threads here
# use a cicle if needed
thread = PrintNumber(0) # first 5000 numbers
thread.start()
thread = PrintNumber(5000) # next 5000
thread.start()
Coded from mind and have not tested it, should be working anyway

In MAYA 2009, is it possible to capture the cube rotate event?

I need to call a function ( Maya-Python ) based on cube rotationX. For that I have to capture the event, programmatically.
I tried using while loop but It stucks in the loop, Nothing can be done in that time.
I tried theading (python), still same.
Can it be done this or other way? If yes, How?
Maya 2009 in Windows XP
Some failed code references:
import maya.cmds as cmds
while (count < 90):
lock = cmds.getAttr('pCube1.rotateX',lock=False)
print lock
count = count + 1
Here Python wise:
#!/usr/bin/python
import thread
import time
# Define a function for the thread
def cubeRotateX( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
try:
thread.start_new_thread( cubeRotateX, ("Thread-1", 2, ) )
except:
print "Error: unable to start thread"
while 1:
pass
It sounds like a scriptJob may be what you're after. Here's a simple example below. However, in this example the callback will only be called when you release the mouse from rotating.
import maya.cmds
def myRotateCallback():
print 'do something'
maya.cmds.scriptJob( attributeChange=['pCube1.rotateX', myRotateCallback] )
If you want to receive continuous callbacks while rotating the cube, you can do that at the maya API level with MNodeMessage::addNodeDirtyPlugCallback.

Categories