【问题标题】:multiprocessing.value clear syntax?multiprocessing.value 语法清晰吗?
【发布时间】:2013-05-05 06:51:44
【问题描述】:

我想使用 multiprocessing.Value 在多个进程中使用变量,但 Python 文档中的语法并不清楚。谁能告诉我应该使用什么类型(我的变量是一个字母),以及将变量名放在哪里?

编辑

我尝试使用管理器在进程之间共享我的信件。但是我现在唯一的东西是Value('ctypes.c_char_p', '(您在这里敲击的键)') 在 Python Shell 中打印,但仍然没有声音。 使用管理器时,控制台似乎也比平时慢了一点。从我击键到Value 出现在屏幕上之间有将近一秒的延迟。

我的代码现在看起来像这样:

#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()

【问题讨论】:

  • 我对您标记为initialization 的代码部分感到困惑。模块顶层的global 语句不执行任何操作。这是完全没有意义的。你打算让eventhitkey 在那里?
  • 这是我忘记删除的旧声明。我认为这不会改变任何事情。
  • 这里真的需要多处理吗?您当然不需要Managervalue 来将参数传递给新进程(只需让multiprocessing 使用pickle 传递字符串)。如果您只是从常规代码而不是在单独的进程中调用它,您的 player 函数是否有效?我根本不认识winsound,所以帮不了太多调试。
  • @Blckknght 我需要同时播放多个声音,而 Python 的 GIL 阻止了它。这就是我需要多处理的原因。
  • 如果您使用相同的参数在单个进程中进行测试,player 函数是否有效?

标签: python multiprocessing


【解决方案1】:

multiprocessing.Value 没有特殊的语法,它只是一个和其他类一样的类。 Value 构造函数的签名描述得非常完美

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

返回从共享内存分配的ctypes 对象。默认情况下,返回值实际上是对象的同步包装器。

typecode_or_type 确定返回对象的类型:它要么是 ctypes 类型,要么是所用类型的单字符类型代码 通过array 模块。 *args 被传递给构造函数 输入。

如果lockTrue(默认值),则创建一个新的锁对象来同步对值的访问。如果锁是LockRLock 对象然后将用于同步访问 价值。如果lockFalse 则访问返回的对象将 不会被锁自动保护,所以不一定 “过程安全”。

你甚至有一些使用它的例子afterwards。特别是typecode_or_type 可以是array 模块文档中列出的类型代码之一(例如'i' 用于有符号整数,'f' 用于浮点等)或ctypes 类型,如@ 987654343@等

如果你想要一个包含单个字母的Value,你可以这样做:

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

更新

您的代码的问题是类型代码'c' 表示字符不是字符串。 如果你想保存一个字符串,你可以使用类型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!'

对于 Python 3,请使用 c_wchar_p 而不是 c_char_p

【讨论】:

  • 试过了,但后来我的多处理代码行出现错误:Exception in Tkinter callback Traceback (most recent call last): File "C:\Program Files (x86)\Python\lib\tkinter\__init__.py", line 1399, in __call__ return self.func(*args) File "G:\Projet final\Test audio\test4-2.py", line 16, in key hitkey = multiprocessing.Value('c', temp, False)
  • File "C:\Program Files (x86)\Python\lib\multiprocessing\__init__.py", line 252, in Value return Value(typecode_or_type, *args, **kwds) File "C:\Program Files (x86)\Python\lib\multiprocessing\sharedctypes.py", line 96, in Value obj = RawValue(typecode_or_type, *args) File "C:\Program Files (x86)\Python\lib\multiprocessing\sharedctypes.py", line 73, in RawValue obj.__init__(*args) TypeError: __init__ expected at most 1 arguments, got 2
  • @FalafHellFalafHell 你做错了什么。 向我们展示代码!
  • @FalafHellFalafHell Value 类型的参数不是字符串'ctypes.c_char_p'。是来自模块ctypes对象 c_char_p。仔细阅读我回答中的最后一个例子。
  • 我发现v = mp.Value(ctypes.c_char_p, "Hello, World!") 存在问题,导致分段违规,因为我推测共享内存中的项目是指向字符串的指针,而不是字符串本身。
【解决方案2】:

我认为您遇到的最初问题(导致TypeError)是因为multiprocessing.Value 构造函数的lock 参数是仅关键字参数。您需要致电 multiprocessing.Value("c", temp, lock=False) 以便它执行您想要执行的操作。

但是,我认为您根本不需要使用 Value 对象。您将密钥代码作为参数传递给您的其他进程,而 Value 根本没有被使用。我会完全摆脱它:

def key(event): 
   instance = multiprocessing.Process(target=player, args=(event.char,)) 
   instance.start()

【讨论】:

  • 我试过hitkey = multiprocessing.Value('c', temp, lock=False),我有一个TypeError: one character string expected 错误。我也尝试不使用Value 对象,但同样没有声音播放。
  • 正如我在回答中已经指出的那样,问题是'c' 需要一个 single 字符,而 Falaf 正在传递一个字符串。使用ctypes.c_char_p 有效。
  • 对,我忘了。修好了,但还是有这个TypeError: this type has no size
  • @FalafHellFalafHell:你试过没有Value的版本吗?无论event.char 是什么,它都应该工作。它适用于任何字符串。当然,如果字符串不是您所期望的,其他进程可能找不到您希望它播放的wav 文件。您可能需要打印出event.char 进行调试,以确保它符合您的预期。
  • @Blckknght 是的,我试过instance = multiprocessing.Process(target=player, args=(event.char,))print(event.char),但我得到的唯一结果是打印出来的字母,没有声音。
猜你喜欢
  • 2018-08-14
  • 2020-04-25
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 2013-02-14
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
相关资源
最近更新 更多