Starting my script off with:
for i in range(threads):
t = Thread(target=getSizes, args=(i,))
t.start()
Then when one of the threads is able to get the variables needed for the other functions it does:
for i in range(threads):
t = Thread(target=cart, args=(i, sizes, prod_name, product_id))
t.start()
Is there any way to till all threads started on getSizes() and then start new threads on cart()?
If your worker function does work in a loop, it can use a common resource like an Event to signal when work is complete and it should return. Here is an example
import threading
import time
import random
def getSizes(done_event):
while not done_event.is_set():
print("get size")
if random.randint(0, 20) == 10:
print("got size")
done_event.set()
do_cart()
else:
time.sleep(random.random())
print("sizes done")
def do_getSizes():
event = threading.Event()
threads = []
for i in range(5):
t = threading.Thread(target=getSizes, args=(event,))
t.start()
threads.append(t)
for t in threads:
t.join()
def cart():
print("I haz the cartz")
def do_cart():
time.sleep(1)
threads = []
for i in range(5):
t = threading.Thread(target=cart)
t.start()
threads.append(t)
for t in threads:
t.join()
do_getSizes()
Related
Figured it out, i think? Runs as expected. I'm not able to view the original code so I wrote this new one up. Is there a better way to do this?
import time
import threading
def threadee():
f = open(r'log.txt')
for line in f:
print(line)
time.sleep(0.2)
def threader():
while True:
threadee()
def main():
thread = threading.Thread(target=threader)
thread.start()
while True:
print('main thread running')
print(threading.enumerate())
time.sleep(1)
if __name__ == '__main__':
main()
I have a class that runs an infinite loop using threads to populate a thread-safe queue:
from threading import Thread
from Queue import Queue
import time
class factory:
def __init__(self):
self.running = True
self.q = Queue()
t = Thread(target=self.count_indefinitely)
t.start()
time.sleep(3)
print self.q.qsize()
def count_indefinitely(self):
i = 0
while self.running:
i += 1
self.q.put(i)
if __name__ == '__main__':
f = factory()
time.sleep(2)
print 'Hello!'
f.running = False
The code reaches the part where I need to print out the size of the queue. However, I can't get it to print "hello" in the main function. How should I go about fixing this?
I have a code something like this,
import threading
class Mythread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print('do some processing')
if __name__=='__main__':
while Ture:
val = raw_input('next thread')
t = MyThread()
t.start()
t.join()
The question is how can I carry on with main function without blocking the main because t.join() stop the main until t does not finish?
You should put code in the "code" tag or else it's not really readable.
And you just have to do something like that.
if name == 'main':
#Thread creation
allThreads = []
while True:
val = raw_input('next thread')
newThread = MyThread()
newThread.start()
allThreads.append(newThread)
#You can do something here
#Waiting for all threads to stop
for thread in allThreads:
thread.join()
I have a list of threads. The following code releases the mutex lock at the end of the block using the 'with' statement. This is very useful as it allows the user to cycle through each thread and choose to stop it or keep it running.
import threading
#subclass with state
class Mythread(threading.Thread):
def __init__(self,myId, astr, mutex):
self.myId = myId
self.astr = astr
self.mutex = mutex
threading.Thread.__init__(self)
def run(self):
while True:
with self.mutex:
print('[%s] => %s' % (self.myId, self.astr))
ans=raw_input("Enter s to stop thread...")
if ans == 's':
break
stdoutmutex = threading.Lock()
threads = []
for i,j in zip(range(7),['A', 'B', 'C','D','E','F','G']):
thread = Mythread(i,j,stdoutmutex)
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
To ensure the threads are cycled through in the order as found in the 'threads' list, I've used the Queue module to control the order of the thread locks:
thread = q.get()
with thread.mutex:
The modified script:
import threading, Queue
#subclass with state
class Mythread(threading.Thread):
def __init__(self,myId, astr, mutex):
self.myId = myId
self.astr = astr
self.mutex = mutex
threading.Thread.__init__(self)
def run(self):
while True:
thread = q.get()
with thread.mutex:
print('[%s] => %s' % (self.myId, self.astr))
ans=raw_input("Enter s to stop thread...")
if ans == 's':
q.task_done()
break
else:
q.put(thread)
stdoutmutex = threading.Lock()
threads = []
q = Queue.Queue()
for i,j in zip(range(7),['A', 'B', 'C','D','E','F','G']):
thread = Mythread(i,j,stdoutmutex)
threads.append(thread)
for thread in threads:
q.put(thread)
thread.start()
for thread in threads:
thread.join()
This appears to work as the correct thread order A,B,C... is sent to the standard output. However, can it be verified that the Queue is working and it isn't just a coincidence?
I have a python 3.4.3, postgreSQL 9.4, aiopg-0.7.0. An example of multi-threaded applications, was taken from this site. How to use the pool? The thread hangs when the operation of the select.
import time
import asyncio
import aiopg
import functools
from threading import Thread, current_thread, Event
from concurrent.futures import Future
class B(Thread):
def __init__(self, start_event):
Thread.__init__(self)
self.loop = None
self.tid = None
self.event = start_event
def run(self):
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
self.tid = current_thread()
self.loop.call_soon(self.event.set)
self.loop.run_forever()
def stop(self):
self.loop.call_soon_threadsafe(self.loop.stop)
def add_task(self, coro):
"""this method should return a task object, that I
can cancel, not a handle"""
def _async_add(func, fut):
try:
ret = func()
fut.set_result(ret)
except Exception as e:
fut.set_exception(e)
f = functools.partial(asyncio.async, coro, loop=self.loop)
if current_thread() == self.tid:
return f() # We can call directly if we're not going between threads.
else:
# We're in a non-event loop thread so we use a Future
# to get the task from the event loop thread once
# it's ready.
fut = Future()
self.loop.call_soon_threadsafe(_async_add, f, fut)
return fut.result()
def cancel_task(self, task):
self.loop.call_soon_threadsafe(task.cancel)
#asyncio.coroutine
def test(pool, name_task):
while True:
print(name_task, 'running')
with (yield from pool.cursor()) as cur:
print(name_task, " select. ")
yield from cur.execute("SELECT count(*) FROM test")
count = yield from cur.fetchone()
print(name_task, ' Result: ', count)
yield from asyncio.sleep(3)
#asyncio.coroutine
def connect_db():
dsn = 'dbname=%s user=%s password=%s host=%s' % ('testdb', 'user', 'passw', '127.0.0.1')
pool = yield from aiopg.create_pool(dsn)
print('create pool type =', type(pool))
# future.set_result(pool)
return (pool)
event = Event()
b = B(event)
b.start()
event.wait() # Let the loop's thread signal us, rather than sleeping
loop_db = asyncio.get_event_loop()
pool = loop_db.run_until_complete(connect_db())
time.sleep(2)
t = b.add_task(test(pool, 'Task1')) # This is a real task
t = b.add_task(test(pool, 'Task2'))
while True:
time.sleep(10)
b.stop()
Not return result in 'yield from cur.execute("SELECT count(*) FROM test")'
Long story short: you cannot share aiopg pool object from different event loops.
Every aiopg.Pool is coupled to event loop. If you don't specify loop parameter explicitly it is taken from asyncio.get_event_loop() call.
So it your example you have a pool coupled to event loop from main thread.
When you execute db query from separate thread you trying to accomplish it by executing thread's loop, not the main one. It doesn't work.