第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何讓高頻線程與低頻更新的類對話?

如何讓高頻線程與低頻更新的類對話?

慕田峪7331174 2022-06-02 16:16:32
概括我正在做一個(gè)需要低 delta_t 的實(shí)時(shí)物理模擬。我已將此模擬連接到 python-arcade 游戲窗口以實(shí)時(shí)顯示信息。我為物理線程制作了一個(gè)單獨(dú)的線程,因?yàn)槲锢砭€程中有一些昂貴的矩陣乘法。然后,當(dāng)更新完成時(shí),我設(shè)置游戲窗口類的結(jié)果狀態(tài),游戲窗口在繪制新框架時(shí)可以顯示這些狀態(tài)。因此,我的想法是游戲窗口類只需要擔(dān)心在屏幕上的繪制,而物理線程負(fù)責(zé)所有的計(jì)算。但是,游戲窗口和線程之間的通信存在瓶頸,我不知道是否有深入的了解。我想做的最小表示:import threadingimport timeimport mathimport arcadeclass DisplayWindow(arcade.Window):    def __init__(self):        super().__init__(width=400, height=400)        self.state = 0        self.FPS = 0    def set_state(self, state):        self.state = state    def on_update(self, delta_time: float):        self.FPS = 1. / delta_time    def on_draw(self):        arcade.start_render()        arcade.draw_text(f'FPS: {self.FPS:0.2f}', 20, 20, arcade.color.WHITE)        arcade.draw_rectangle_filled(center_x=self.state * self.width,                                     center_y=self.height/2,                                     color=arcade.color.WHITE,                                     tilt_angle=0,                                     width=10,                                     height=10)# Thread to simulate physics.def simulation(display):    t_0 = time.time()    while True:        # Expensive calculation that needs high frequency:        t = time.time() - t_0        x = math.sin(t) / 2 + 0.5       # sinusoid for demonstration        # Send it to the display window        display.set_state(state=x)        # time.sleep(0.1)               # runs smoother with thisdef main():    display_window = DisplayWindow()    physics_thread = threading.Thread(target=simulation, args=(display_window,), daemon=True)    physics_thread.start()    arcade.run()    return 0if __name__ == '__main__':    main()預(yù)期結(jié)果:高幀率的平滑模擬。街機(jī)窗口只需以 30 或 60 fps 運(yùn)行 on_draw。它只需要畫一些東西。實(shí)際結(jié)果:物理循環(huán)運(yùn)行速度超快并調(diào)用 FPS drop。當(dāng)我在物理線程中添加 time.sleep(0.1) 時(shí),整個(gè)事情變得更加順暢,我猜出于某種原因set_state( _ )會(huì)減慢繪制循環(huán)。
查看完整描述

2 回答

?
郎朗坤

TA貢獻(xiàn)1921條經(jīng)驗(yàn) 獲得超9個(gè)贊

Python 線程可能不是您嘗試做的工作的理想工具。

盡管將 Python 線程視為并發(fā)運(yùn)行可能很誘人,但事實(shí)并非如此:全局解釋器鎖 (GIL) 只允許一個(gè)線程控制 Python 解釋器。更多信息

正因?yàn)槿绱耍?code>arcade.Window對象無法及早控制 Python 解釋器并運(yùn)行其所有更新函數(shù),因?yàn)?GIL 始終“專注”simulationphysics_thread.

GIL 只會(huì)在physics_thread運(yùn)行一定數(shù)量的指令或使用which 在線程上執(zhí)行physics_thread設(shè)置為睡眠后才釋放對 的關(guān)注并在其他線程上尋找其他事情要做。這正是您憑經(jīng)驗(yàn)發(fā)現(xiàn)的恢復(fù)程序預(yù)期行為的方法。time.sleep()

這是一個(gè)稱為線程饑餓的典型問題的示例,可以通過使用多處理庫來解決。這會(huì)帶來更多的復(fù)雜性,但會(huì)將您的 CPU 密集型計(jì)算和基于事件的輕量級(jí)接口分開在不同的進(jìn)程中,從而解決您的問題。


查看完整回答
反對 回復(fù) 2022-06-02
?
拉丁的傳說

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超8個(gè)贊

我研究了使用多處理而不是線程。


該multiprocessing.Pipe對象確保了雙工通信并使整個(gè)事情變得更加順暢。我現(xiàn)在還可以確保模擬的實(shí)時(shí)運(yùn)行。


兩邊的每個(gè)更新循環(huán),只需使用send()andrecv()命令。尚未測試邊緣情況,但似乎工作順利。


我將修改添加到上面發(fā)布的示例中:


import time

import arcade

from multiprocessing import Process, Pipe

from math import sin, pi



class DisplayWindow(arcade.Window):

    def __init__(self, connection: Pipe):

        super().__init__(500, 500)


        self.connection: Pipe = connection    # multiprocessing.Pipe


        self.position: float = 0               # GUI Display state

        self.user_input: float = 1.0           # Input to simulation

        self.FPS: float = 0                    # Frames per second estimation


    def on_update(self, delta_time: float):

        self.FPS = 1. / delta_time


        # Communicate with simulation:

        self.connection.send(self.user_input)

        self.position = self.connection.recv()


    def on_draw(self):

        arcade.start_render()

        arcade.draw_text(f'FPS: {self.FPS:0.0f}', 20, 20, arcade.color.WHITE)

        arcade.draw_point(self.position, self.height/2, arcade.color.WHITE, 10)


    def on_key_release(self, symbol: int, modifiers: int):

        if symbol == arcade.key.W:

            self.user_input = 1.8

        elif symbol == arcade.key.S:

            self.user_input = 0.3



# Separate Process target to simulate physics:

def simulation(connection: Pipe):

    t_0 = time.time()

    while True:

        freq = connection.recv() * 2 * pi       # Receive GUI user input


        t = time.time() - t_0

        x = sin(freq * t) * 250 + 250


        connection.send(x)                      # Send state to GUI


def main():

    parent_con, child_con = Pipe()

    display_window = DisplayWindow(connection=parent_con)

    physics = Process(target=simulation, args=(child_con,), daemon=True)

    physics.start()

    arcade.run()

    physics.terminate()

    return 0


if __name__ == '__main__':

    main()


查看完整回答
反對 回復(fù) 2022-06-02
  • 2 回答
  • 0 關(guān)注
  • 165 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)