You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中运行音频与GDI PATCOPY效果且避免音频中断

问题分析与解决方案

问题核心在于GDI线程是CPU密集型任务,50000次无停顿的PATCOPY操作几乎占满CPU时间片,导致音频线程抢不到执行机会;加上线程默认优先级相同,winsound的阻塞Beep调用被频繁打断。另外你的GDI代码还存在资源释放错误,会加剧系统资源紧张。

具体修复步骤:


1. 提高音频线程优先级

给音频线程设置更高的系统优先级,让系统优先处理音频任务:

# 需要额外导入
from win32api import SetThreadPriority, GetCurrentThread
from win32con import THREAD_PRIORITY_HIGHEST

def func1():
    import winsound
    # 设置当前线程为最高优先级
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)
    
    freq = 500         
    dur = 1000
    # ... 其余蜂鸣参数不变
    winsound.Beep(freq, dur)
    # ... 其余Beep调用不变

2. 优化GDI循环,增加微小延迟

在GDI循环中加入Sleep(0),让当前线程主动放弃剩余时间片,给音频线程执行机会:

def func2():
    desk = GetDC(0)
    x = GetSystemMetrics(0)
    y = GetSystemMetrics(1)
    print(x, y)
    
    for i in range(50000):
        brush = CreateSolidBrush(RGB(
            randrange(255),
            randrange(255),
            randrange(255)
        ))
        SelectObject(desk, brush)
        PatBlt(desk, randrange(x), randrange(y), randrange(100), randrange(200), PATCOPY)
        DeleteObject(brush)
        # 主动让出CPU时间片
        Sleep(0)
    
    # 修复资源释放:GetDC获取的DC用ReleaseDC释放,参数顺序是窗口句柄+DC句柄
    ReleaseDC(0, desk)
    # GetDC获取的DC不需要DeleteDC,只有CreateDC创建的才需要

3. 修复GDI资源释放错误

原来的ReleaseDC(desk, GetDesktopWindow())参数顺序完全错误,正确的调用是ReleaseDC(0, desk)(因为GetDC(0)是获取屏幕的DC,窗口句柄为0),并且不需要调用DeleteDC(该函数仅用于释放CreateDC创建的设备上下文)。


修改后的完整代码

from threading import Thread
import os    
from win32gui import *
from win32api import *
from win32ui import *
from win32con import *
from random import *
from win32api import SetThreadPriority, GetCurrentThread
from win32con import THREAD_PRIORITY_HIGHEST

def func1():
    import winsound
    # 设置音频线程为最高优先级
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)

    freq = 500         
    dur = 1000
    freq1 = 600
    dur1 = 200
    freq2 = 100
    dur2 = 100
    freq3 = 900
    dur3 = 120
    freq4 = 700
    dur4 = 3000
    freq5 = 9000
    dur5 = 100
    freq6 = 5000
    dur6 = 500
    freq7 = 700
    dur7 = 700
    freq8 = 900
    dur8 = 400
    freq9 = 300
    dur9 = 900 
    winsound.Beep(freq, dur)
    winsound.Beep(freq1, dur1)
    winsound.Beep(freq2, dur2)
    winsound.Beep(freq3, dur3)
    winsound.Beep(freq4, dur4)
    winsound.Beep(freq5, dur5)
    winsound.Beep(freq6, dur6)
    winsound.Beep(freq7, dur7)
    winsound.Beep(freq8, dur8)
    winsound.Beep(freq9, dur9)

def func2():
    desk = GetDC(0)
    x = GetSystemMetrics(0)
    y = GetSystemMetrics(1)
    print(x, y)
    
    for i in range(50000):
        brush = CreateSolidBrush(RGB(
            randrange(255),
            randrange(255),
            randrange(255)
        ))
        SelectObject(desk, brush)
        PatBlt(desk, randrange(x), randrange(y), randrange(100), randrange(200), PATCOPY)
        DeleteObject(brush)
        # 让出CPU时间片,给音频线程执行机会
        Sleep(0)
    
    # 正确释放DC
    ReleaseDC(0, desk)

if __name__ == '__main__':
    Thread(target=func1).start()
    Thread(target=func2).start()

内容的提问来源于stack exchange,提问作者SkyKrye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 17:39:24