Sharing objects between processes
ET
phu at 2drpg.org
Mon Mar 9 19:48:27 EDT 2009
On Mon, 2009-03-09 at 14:57 -0700, Aaron Brady wrote:\
>
> import threading
> import time
>
>
> class Globals:
> cont= True
> content= { }
> lock_content= threading.Lock( )
>
> def read( ):
> out= open( 'temp.txt', 'w' )
> while Globals.cont:
> with Globals.lock_content:
> rep= repr( Globals.content )
> out.write( rep )
> out.write( '\n' )
> time.sleep( 1 )
>
> def write_random( ):
> import random
> while Globals.cont:
> num= random.randint( 1, 100 )
> letter= random.choice( 'abcedfghij' )
> with Globals.lock_content:
> Globals.content[ num ]= letter
> time.sleep( 1 )
>
> def write_user_inp( ):
> next_key= 101
> while Globals.cont:
> us_in= input( '%i--> '% next_key )
> if not us_in:
> Globals.cont= False
> return
> us_in= us_in[ :10 ]
> print( 'You entered: %s'% us_in )
> with Globals.lock_content:
> Globals.content[ next_key ]= us_in
> next_key+= 1
>
> read_thr= threading.Thread( target= read )
> read_thr.start( )
> wri_rand_thr= threading.Thread( target= write_random )
> wri_rand_thr.start( )
> wri_user_thr= threading.Thread( target= write_user_inp )
> wri_user_thr.start( )
>
> read_thr.join( )
> wri_rand_thr.join( )
> wri_user_thr.join( )
>
> Which is about the complexity of what you asked for. It wasn't tested
> with multiprocessing. Ver 3.0.1.
> --
> http://mail.python.org/mailman/listinfo/python-list
Wow, thanks for taking the time to put that together! Unfortunately,
I've attempted to modify it to use multiprocessing without success.
This works when the threading import is used, falls through with
multiprocessing, and runs with processing, though modifications to the
Globals class do not stick:
from __future__ import with_statement
#from threading import Thread as ControlType, Lock
#from multiprocessing import Process as ControlType, Lock
from processing import Process as ControlType, Lock
import time
class Globals:
cont= True
content= { }
lock_content= Lock( )
inputs = ['itext', 'text input', 'testing text', 'test']
def read( ):
#out= open( 'temp.txt', 'w' )
while Globals.cont:
with Globals.lock_content:
rep= repr( Globals.content )
print rep
#out.write( rep )
#out.write( '\n' )
time.sleep( 1 )
def write_random( ):
import random
while Globals.cont:
num= random.randint( 1, 100 )
letter= random.choice( 'abcedfghij' )
with Globals.lock_content:
Globals.content[ num ]= letter
time.sleep( 1 )
def write_user_inp( ):
import random
next_key= 101
while Globals.cont:
if len(Globals.inputs):
us_in = Globals.inputs.pop()
else:
Globals.cont= False
return
us_in= us_in[ :10 ]
print( 'You entered: %s'% us_in )
with Globals.lock_content:
Globals.content[ next_key ]= us_in
next_key+= 1
time.sleep( 1 )
read_thr= ControlType( target= read )
read_thr.start( )
wri_rand_thr= ControlType( target= write_random )
wri_rand_thr.start( )
wri_user_thr= ControlType( target= write_user_inp )
wri_user_thr.start( )
read_thr.join( )
wri_rand_thr.join( )
wri_user_thr.join( )
However, I think I (freaking finally) managed to get this working after
reading the syncmanager documentation for the umpteenth time; it
involves extending the SyncManager class to allow an arbitrary class as
a member (this might be possible just by calling register(...) on
SyncManager itself, but this is how the doc said to handle it). It also
provides its own Lock implementations, which I used within the new
managed class to apply with locking:
from __future__ import with_statement
from multiprocessing import Process, Lock, current_process
from multiprocessing.managers import SyncManager
from random import choice, randint
from time import sleep
class TestClass(object):
name = 'testclassname'
lock = None
def setval(self, value):
with self.lock:
self.name = value
def getval(self):
with self.lock:
return self.name
def __init__(self, lock):
self.lock = lock
class TestManager(SyncManager):
pass
TestManager.register('TC', TestClass)
manager = TestManager()
manager.start()
class TestProcess(Process):
obj = None
new_name = None
def __init__(self, obj):
self.obj = obj
Process.__init__(self)
def run(self):
for i in range(5000):
name = choice('abcedfghij') + str(randint(20, 500))
print "setting from", obj.getval(), "to", name, "in",
current_process().name
self.obj.setval(name)
# sleep(1)
if __name__ == '__main__':
lock = manager.Lock()
obj = manager.TC(lock)
p1 = TestProcess(obj)
p2 = TestProcess(obj)
p1.start()
p2.start()
p1.join()
p2.join()
Putting this up for posterity in case anyone with the same problem
happens upon it. Thanks again, Aaron, for working through this with me!
More information about the Python-list
mailing list