我正在做一个从udp套接字接收样本的音频播放器,一切正常.但是当我实现一个丢失隐藏算法时,播放器未能以例外速率继续产生静音(每个10ms发送一个多个160字节的列表).
当用pyaudio播放音频时,使用阻塞调用写入来播放一些样本,我注意到它在样本持续时间内平均被阻止.所以我创建了一个新的专用流程来播放样本.
主进程处理音频输出流,并使用multiprocessing.Pipe将结果发送到该进程.我决定使用multiprocessing.Pipe,因为它应该比其他方式更快.
不幸的是,当我在虚拟机上运行该程序时,比特率是我在快速PC上获得的一半,它没有达到目标比特率.
经过一些测试,我得出结论,造成延迟的原因是Pipe的功能send.
我做了一个简单的基准测试脚本(见下文),以了解传输到流程的各种方法之间的差异.该脚本不断发送[b'\x00'*160]5秒,并计算总共发送字节对象的字节数.我测试了以下发送方法:"不发送",多处理.管道,多处理.Queue,multiprocessing.Manager,multiprocessing.Listener/Client,最后是socket.socket:
我的"快速"PC运行窗口7 x64的结果:
test_empty : 1516076640
test_pipe : 58155840
test_queue : 233946880
test_manager : 2853440
test_socket : 55696160
test_named_pipe: 58363040
Run Code Online (Sandbox Code Playgroud)
运行Windows 7 x64的VirtualBox VM guest虚拟机的结果,运行Windows 7 x64的主机:
test_empty : 1462706080
test_pipe : 32444160
test_queue : 204845600
test_manager : 882560
test_socket : 20549280
test_named_pipe: 35387840
Run Code Online (Sandbox Code Playgroud)
from multiprocessing import Process, Pipe, Queue, Manager
from multiprocessing.connection import Client, Listener
import time
FS = "{:<15}:{:>15}"
def test_empty():
s = time.time()
sent = 0
while …Run Code Online (Sandbox Code Playgroud) 在 Windows 上使用 python 3.4。
我正在尝试终止模拟一个人按 Ctrl+C(在 linux 上为 Ctrl+D)的子进程。
我只是添加了处理程序来检查信号是否正在被处理。我使用了这个问题的想法
目标是捕获 KeyboardInterrupt (SIGINT),并释放资源。但如果 SIGINT 不是来自键盘,似乎不会抛出异常。这就是为什么我创建了一个处理程序,但该进程似乎根本没有运行该处理程序......
import multiprocessing
import time
import signal
import signal
import os
import sys
def handler(signal, frame):
print("handler!!!")
sys.exit(10)
def worker():
p = multiprocessing.current_process()
try:
signal.signal(signal.SIGINT,handler)
print("[PID:{}] acquiring resources".format(p.pid))
while(True):
#working...
time.sleep(0.5)
except (KeyboardInterrupt, SystemExit):
pass
finally:
print("[PID:{}] releasing resources".format(p.pid))
if __name__ == "__main__":
lst = []
for i in range(1):
p = multiprocessing.Process(target=worker)
p.start()
lst.append(p)
time.sleep(3)
for p in lst:
os.kill(p.pid,signal.SIGINT)
p.join()
print(p)
print(p.exitcode) …Run Code Online (Sandbox Code Playgroud) 我想了解以下指南:
使用spawn或forkserver start方法时,需要对多处理中的许多类型进行选择,以便子进程可以使用它们.但是,通常应避免使用管道或队列将共享对象发送到其他进程.相反,您应该安排程序,以便需要访问其他地方创建的共享资源的进程可以从祖先进程继承它.
我正在运行Windows,因此生成了新进程,这是否意味着只有分叉进程可以继承?
流媒体端不断发送 2048 字节的声音样本以及作为整数的时间,一起发送到使用 pickle.dumps 进行腌制的元组中,然后将其以 UDP 数据包发送到接收器,然后接收器将其解开并缓冲它然后播放声音样本。
使用 python 3 一切都很好,接收器上的比特/秒速度是预期的。
当我在python 2.7中运行streamer时,速度更快了!我觉得 python 2 更快。
然后我用wireshark检查了接收方正在接收的UDP数据包,它们比需要的要大。
流光端:
while True:
data = next(gen)
print("data:{}".format(len(data)))
stime +=1
msg = (stime,data)
payload = pickle.dumps(msg)
print("payload:{}".format(len(payload)))
bytes_sent = s.sendto(payload,addr)
time.sleep(INTERVAL)
Run Code Online (Sandbox Code Playgroud)
接收端:
while True:
if stop_receiving.get():
break
try:
(payload,addr) = self.sock.recvfrom(32767)
(t,data) = pickle.loads(payload,encoding="bytes")
if stime >= self.frame_time.get():
self.frames.put((t,data))
except socket.timeout:
pass
Run Code Online (Sandbox Code Playgroud)
在使用 pickle format 3 的 python 3.4 上,如果我 pickle.dumps 一个整数和 2048 字节的元组,我会得到 2063 字节。
奇怪的是,在使用 pickle format 2 的 python 2.7 上,我得到了 …