Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multiprocessing.value clear syntax?

I want to use multiprocessing.Value to use a variable in multiple processes, but the syntax is not clear on Python's documentation. Can anyone tell me what should I use as type (my variable is a letter), and where to put my variable's name ?

EDIT

I tried using the Manager to share my letter between processes. But the only thing I have now is Value('ctypes.c_char_p', '(The key you hit here)') printed in the Python Shell and still no sound. The console also seems a bit slower than usual when using the manager. There's an almost one second delay between the time I hit the key and when the Value appears on screen.

My code now looks like this :

#Import 
from tkinter import * 
import wave 
import winsound 
import multiprocessing 

#Functions 

def key(event):

     temp = event.char
     manager = multiprocessing.Manager()
     manager.Value(ctypes.c_char_p, temp)
     hitkey = manager.Value(ctypes.c_char_p, temp)
     instance = multiprocessing.Process(target=player, args=(hitkey,)) 
     instance.start()



def player(hitkey):
     print(hitkey + "1")
     winsound.PlaySound(hitkey + '.wav', winsound.SND_FILENAME|winsound.SND_NOWAIT|winsound.SND_ASYNC) 


if __name__ == "__main__":



     #Initialisation 
     fenetre = Tk() 
     frame = Frame(fenetre, width=200, height=100)
     #TK

     frame.focus_set()
     frame.bind("<Key>", key)
     frame.pack()
     fenetre.mainloop()
like image 687
Pollux Avatar asked May 10 '13 14:05

Pollux


People also ask

How do you pass arguments in multiprocessing in Python?

Passing Keyword Arguments to Multiprocessing Processes We can also pass in arguments corresponding to the parameter name using the kwargs parameter in the Process class. Instead of passing a tuple, we pass a dictionary to kwargs where we specify the argument name and the variable being passed in as that argument.

How do you stop a multiprocessing process?

A process can be killed by calling the Process. terminate() function. The call will only terminate the target process, not child processes. The method is called on the multiprocessing.

What is multiprocessing dummy?

dummy module module provides a wrapper for the multiprocessing module, except implemented using thread-based concurrency. It provides a drop-in replacement for multiprocessing, allowing a program that uses the multiprocessing API to switch to threads with a single change to import statements.


2 Answers

There is no special syntax for multiprocessing.Value, it's just a class like any other. The signature of the Value constructor is perfectly well described:

multiprocessing.Value(typecode_or_type, *args[, lock])

Return a ctypes object allocated from shared memory. By default the return value is actually a synchronized wrapper for the object.

typecode_or_type determines the type of the returned object: it is either a ctypes type or a one character typecode of the kind used by the array module. *args is passed on to the constructor for the type.

If lock is True (the default) then a new lock object is created to synchronize access to the value. If lock is a Lock or RLock object then that will be used to synchronize access to the value. If lock is False then access to the returned object will not be automatically protected by a lock, so it will not necessarily be “process-safe”.

You even have some examples of its use afterwards. In particolar the typecode_or_type can be one of the typecodes that are listed in the documentation for the array module(e.g. 'i' for signed integer, 'f' for float etc.) or a ctypes type, like ctypes.c_int etc.

If you want to have a Value containing a single letter you can do:

>>> import multiprocessing as mp
>>> letter = mp.Value('c', 'A')
>>> letter
<Synchronized wrapper for c_char('A')>
>>> letter.value
'A'

Update

The problem with your code is that the typecode 'c' means character not string. If you want to hold a string you can use the type ctypes.c_char_p:

>>> import multiprocessing as mp
>>> import ctypes
>>> v = mp.Value('c', "Hello, World!")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/multiprocessing/__init__.py", line 253, in Value
    return Value(typecode_or_type, *args, **kwds)
  File "/usr/lib/python2.7/multiprocessing/sharedctypes.py", line 99, in Value
    obj = RawValue(typecode_or_type, *args)
  File "/usr/lib/python2.7/multiprocessing/sharedctypes.py", line 73, in RawValue
    obj.__init__(*args)
TypeError: one character string expected
>>> v = mp.Value(ctypes.c_char_p, "Hello, World!")
>>> v
<Synchronized wrapper for c_char_p(166841564)>
>>> v.value
'Hello, World!'

For Python 3, use c_wchar_p instead of c_char_p

like image 70
Bakuriu Avatar answered Sep 18 '22 15:09

Bakuriu


I think the original issue you were having (causing the TypeError) was because the lock argument to the multiprocessing.Value constructor is a keyword-only argument. You need to call multiprocessing.Value("c", temp, lock=False) in order for it to do what you were wanting to do.

However, I don't think you need to use a Value object at all. You're passing the keycode as an argument to your other process, and the Value isn't being used at all. I'd get rid of it completely:

def key(event): 
   instance = multiprocessing.Process(target=player, args=(event.char,)) 
   instance.start()
like image 39
Blckknght Avatar answered Sep 19 '22 15:09

Blckknght