Re: [python-win32] Restart/re-run a thread

2011-10-27 Thread geoff
The python docs are pretty clear that there is no way to external stop a
thread and this was a design decision.

Typically, I have used a threading.Event to control the actions of the
worker threads from a loop in the main program.

Setup each worker thread as a loop using the event.wait() method to block
the loop.   When you are ready for all of the threads to proceed, use the
controller thread and event.set().  All of the worker threads will exit the
blocking state of their loop and proceed with execution.  Once finished,
they return to the  event.wait() mode.

To stop the threads, I typically use another thread.Event object called
keepgoing and test for that at the top of the worker threads processing
loop.  When the threads have finished processing and you want them to stop,
you can set the keepgoing event to false.


The example below is from memory, so be careful;

keepgoing = threading.Event()
keepgoing.set()   # evaluates to True

startprocess = threading.Event()
startprocess.clear()  # evaluates to False

class worker(threading.Thread):
def __init__(self, keepgoing, startprocess):
 while keepgoing:
  if startprocess:
   ... do someprocessing here
  else:
   startprocess.wait()#blocks the thread waiting
for the event to be set.


Note that if you need to pass objects into the worker thread, I would
suggest placing in a collections.deque.  One the startprocess is set, you
can use deque.pop() to take the object out of the deque in a thread safe
way.

Hope this helps.

BTW, I am not sure if this is for education purposes or for production, but
debugging threads is REALLY HARD, so make sure this is something you really
need to do.
___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32


Re: [python-win32] Restart/re-run a thread

2011-10-27 Thread Ben Timby
Jacob,

What you are looking at is called a thread pool. The simple case you
have now is that you start a thread whenever there is work to do
(playing a sound). The thread does this work, then exits. A thread
pool means you have a set number of threads idling and receiving work
via a queue. When work appears, they perform it and then go back to
idle.

There are thread pool implementations for Python that you could simply
plug into your application.

from multiprocessing.pool import ThreadPool

http://code.activestate.com/recipes/203871-a-generic-programming-thread-pool/

In either case, if you are looking to kill off a thread midway through
the work (cut off the sound before it is done playing). Then you will
need to use a flag to inform the thread that you wish for it to stop
playing sound. This means you need a polling loop that will play a
short sample of the track and then check the flag before playing the
next sample. This way the thread can exit part of the way through the
sound.

A thread pool will not save memory. It saves the setup/teardown of
threads. This is a relatively expensive process, and if an application
starts hundreds of thousands of threads during it's lifetime, this
adds up. Think about it, either way, you will need a number of
concurrent threads that equals the number of sounds you wish to play
concurrently. This means a thread pool will have X threads active
(though idle) at all times. The simple case will have X threads active
(and working) only while the sounds are being played. The only real
advantage of the thread pool is that it avoids setup/teardown, so it
could possibly save some latency when playing a new sound. This is
because a new thread does not need to be initialized, it just has to
wake up and start playing the sound. You have to decide if this
latency is a problem and if so, go the thread pool route. Of course,
Python threads are not native threads, so I think any advantage here
probably washes out. My suggestion is to stick with the simple case.

A simple sound player class can do the whole task for you, and your
code will be much easier to follow and debug. Throwing a thread pool
into the mix will complicate things.

Simple case:

class PlaySound(threading.Thread):
def __init__(self, sound='foobar.wav'):
self.sound = sound
self.running = True
self.sample = 0
threading.Thread.__init__(self):
self.start()

def playsample(self):
soundlib.play(self.sound, startms=self.sample*100, lengthms=100)
self.sample += 100

def run(self):
while self.running:
self.playsample()

def stop(self):
self.running = False

s = PlaySound('explosion.wav')
if user_exited:
s.stop()

The main key here is that instead of playing the whole sound file in
one shot, you play only a small portion of it between polls. This way
the thread can stop mid-sound. You need to use a sound library that
will support breaking a sound into multiple parts in order to achieve
this.

Another option here is to ditch threads altogether and find a sound
library that does async playback. Let it handle this mess for you.

http://docs.python.org/library/winsound.html
___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32


Re: [python-win32] Restart/re-run a thread

2011-10-27 Thread Jacob Kruger
Thanks.

What have also found that seems nice/usable enough is to sort of implement a 
class that inherits from threading.Thread, and then it runs the class's 
functionality in the threaded background, and you can define other functions 
and variables to check state if you want to - something like the following - 
off the top of my head:
#---start of code---
 import threading, time
class myClass(threading.Thread):
  counter = -1
  def __init__(self):
self.counter = 0
threading.Thread.__init__(self)

  def getCount(self):
return self.counter

  def run(self):
while self.counter  60:
  self.counter += 1
  time.sleep(1)
#---end of code---

The partial point is this one will be initiated, but when you then tell your 
instance of the class/object to start(), it sort of automatically tells itself 
to run(), and you can call the getCount() function to get the value of it's 
internal counter variable, etc. - simple example, but seems to work well 
enough, if you get my/the drift, and, what have pretty much found all over the 
'net is that you get told not to try destroy anything manually/yourself, but 
anyway.

Stay well

Jacob Kruger
Blind Biker
Skype: BlindZA
'...fate had broken his body, but not his spirit...'

  - Original Message - 
  From: geoff 
  To: Jacob Kruger 
  Cc: python-win32@python.org 
  Sent: Thursday, October 27, 2011 3:47 PM
  Subject: Re: [python-win32] Restart/re-run a thread


  The python docs are pretty clear that there is no way to external stop a 
thread and this was a design decision.


  Typically, I have used a threading.Event to control the actions of the worker 
threads from a loop in the main program.


  Setup each worker thread as a loop using the event.wait() method to block the 
loop.   When you are ready for all of the threads to proceed, use the 
controller thread and event.set().  All of the worker threads will exit the 
blocking state of their loop and proceed with execution.  Once finished, they 
return to the  event.wait() mode.  


  To stop the threads, I typically use another thread.Event object called 
keepgoing and test for that at the top of the worker threads processing loop. 
 When the threads have finished processing and you want them to stop, you can 
set the keepgoing event to false.




  The example below is from memory, so be careful;


  keepgoing = threading.Event()
  keepgoing.set()   # evaluates to True


  startprocess = threading.Event()
  startprocess.clear()  # evaluates to False


  class worker(threading.Thread):
  def __init__(self, keepgoing, startprocess):
   while keepgoing:
if startprocess:
 ... do someprocessing here
else:
 startprocess.wait()#blocks the thread waiting 
for the event to be set.




  Note that if you need to pass objects into the worker thread, I would suggest 
placing in a collections.deque.  One the startprocess is set, you can use 
deque.pop() to take the object out of the deque in a thread safe way.


  Hope this helps.


  BTW, I am not sure if this is for education purposes or for production, but 
debugging threads is REALLY HARD, so make sure this is something you really 
need to do.



___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32


Re: [python-win32] Restart/re-run a thread

2011-10-27 Thread Jacob Kruger

Thanks.

winsound.PlaySound(file.wav, winsound.SND_ASYNC)

Does handle it asynchronously, but, yes, thanks for complete example.

Am in any case still trying to find/get hold of a sound library of some sort
that will do a bit more, like I want it to, and one called pyaudiere works
fine on my windows7 32bit machine, but refuses to work on my windows7 64bit
machine, same as another wrapper module called sound_lib - and main thing I
would like, apart from just playing/stopping/pausing sounds is to be able to
handle a little bit of 3D, like panning playback etc., but not end of the
world thus far.

Stay well

Jacob Kruger
Blind Biker
Skype: BlindZA
'...fate had broken his body, but not his spirit...'

- Original Message - 
From: Ben Timby bti...@gmail.com

To: python-win32@python.org
Sent: Thursday, October 27, 2011 4:31 PM
Subject: Re: [python-win32] Restart/re-run a thread



Jacob,

What you are looking at is called a thread pool. The simple case you
have now is that you start a thread whenever there is work to do
(playing a sound). The thread does this work, then exits. A thread
pool means you have a set number of threads idling and receiving work
via a queue. When work appears, they perform it and then go back to
idle.

There are thread pool implementations for Python that you could simply
plug into your application.

from multiprocessing.pool import ThreadPool

http://code.activestate.com/recipes/203871-a-generic-programming-thread-pool/

In either case, if you are looking to kill off a thread midway through
the work (cut off the sound before it is done playing). Then you will
need to use a flag to inform the thread that you wish for it to stop
playing sound. This means you need a polling loop that will play a
short sample of the track and then check the flag before playing the
next sample. This way the thread can exit part of the way through the
sound.

A thread pool will not save memory. It saves the setup/teardown of
threads. This is a relatively expensive process, and if an application
starts hundreds of thousands of threads during it's lifetime, this
adds up. Think about it, either way, you will need a number of
concurrent threads that equals the number of sounds you wish to play
concurrently. This means a thread pool will have X threads active
(though idle) at all times. The simple case will have X threads active
(and working) only while the sounds are being played. The only real
advantage of the thread pool is that it avoids setup/teardown, so it
could possibly save some latency when playing a new sound. This is
because a new thread does not need to be initialized, it just has to
wake up and start playing the sound. You have to decide if this
latency is a problem and if so, go the thread pool route. Of course,
Python threads are not native threads, so I think any advantage here
probably washes out. My suggestion is to stick with the simple case.

A simple sound player class can do the whole task for you, and your
code will be much easier to follow and debug. Throwing a thread pool
into the mix will complicate things.

Simple case:

class PlaySound(threading.Thread):
   def __init__(self, sound='foobar.wav'):
   self.sound = sound
   self.running = True
   self.sample = 0
   threading.Thread.__init__(self):
   self.start()

   def playsample(self):
   soundlib.play(self.sound, startms=self.sample*100, lengthms=100)
   self.sample += 100

   def run(self):
   while self.running:
   self.playsample()

   def stop(self):
   self.running = False

s = PlaySound('explosion.wav')
if user_exited:
   s.stop()

The main key here is that instead of playing the whole sound file in
one shot, you play only a small portion of it between polls. This way
the thread can stop mid-sound. You need to use a sound library that
will support breaking a sound into multiple parts in order to achieve
this.

Another option here is to ditch threads altogether and find a sound
library that does async playback. Let it handle this mess for you.

http://docs.python.org/library/winsound.html
___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32


___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32


Re: [python-win32] Restart/re-run a thread

2011-10-27 Thread Jacob Kruger

Will check it out, but will also just say that a few of the game libraries I
have looked at already are of no interest to me, since they produce
inaccessible output/interfaces, but, will look into them a bit more for
sound output...:)

Have also gotten hold of another, sort of TTS module/wrapper that makes use 
of actual screen reader voices in meantime, and which works with python 2.7, 
which is what am using at the moment, but anyway:

http://hg.qwitter-client.net/accessible_output/

Stay well

Jacob Kruger
Blind Biker
Skype: BlindZA
'...fate had broken his body, but not his spirit...'

- Original Message - 
From: Ben Timby bti...@gmail.com

To: Jacob Kruger jac...@mailzone.co.za
Sent: Thursday, October 27, 2011 5:34 PM
Subject: Re: [python-win32] Restart/re-run a thread



Jacob,

May be getting a bit off topic here :-). However, for 3D sound, look
for python game libraries. For cross-platform 3D sound, it looks like
you might want FMOD. There is pySonic, a python wrapper for FMOD.

http://pysonic.sourceforge.net/

FMOD is non-free. However, it is gratis for non-commercial use. I am
sure there are other options as well, but I suggest looking for
libraries geared toward games since they will have the features you
apparently need.

Good luck!



___
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32