簡體   English   中英

我怎樣才能使系統時間在 Python 中運行得更快?

[英]How can i make the system time run faster in Python?

我編寫了一個模擬,涉及在不同控制台中運行的兩個腳本。 這些腳本通過 websocket 相互發送消息。消息以定義的時間間隔發送並包含時間戳(目前我使用datetime.utcnow )。 現在,當我加速模擬時,'自然地, datetime時間戳不受此影響,這意味着它們與模擬時間不同步。 有沒有辦法“加快”系統時間,或者我是否必須編寫自己的時間戳 function 才能確定速度?

編輯:由於我無法更改系統時間,因此我編寫了一個腳本,其中包含一個以我可以確定的速度運行並可以生成時間戳的時鍾。 但是,我找不到在不阻塞控制台的情況下在后台運行此時鍾的方法。 我以為我可以使用 asyncio,但它沒有像我預期的那樣工作。 這是代碼:

import asyncio
import os
import math
simtime = 0
year = 2020
month = 10

try:
    TIMELAPSE = int(os.environ["TIMELAPSE"])
except KeyError:
    TIMELAPSE = 1


async def clock():
    global simtime
    while True:
        await asyncio.sleep(1)
        simtime += 1*TIMELAPSE


def timestamp():
    day = 1 + math.floor(simtime/86400)
    remaining = simtime % 86400
    hours = math.floor(remaining/3600)
    remaining = remaining % 3600
    minutes = math.floor(remaining/60)
    seconds = remaining % 60
    return f"{year}-{month}-{day}::{hours}:{minutes}:{seconds}"


loop = asyncio.get_event_loop()
loop.run_until_complete(clock())
loop.run_forever()

我認為時間會在后台進行,我可以使用 timestamp() function 獲取當前時間。

但是,當我import clock時,它會阻止腳本

我認為這是一個兩部分的問題,首先是關於如何跟蹤游戲中時光倒流,其次是關於如何使用非阻塞后台任務和 asyncio。

首先,看起來您只是每秒添加 simtime += 1*TIMELAPSE 。 在腳本開始時在變量中設置系統時間可能更簡潔,然后當你想檢查當前 simtime 時,你可以再次檢查系統時間並減去起始系統時間,然后將結果乘以你的 TIMELAPSE . 這應該等同於此腳本中使用 simtime 進行的操作,但要簡單得多。

對於這個問題的第二部分,處理異步和非阻塞,我認為你應該使用 asyncio.run_in_executor 來執行后台任務,然后你可以使用 run_until_complete 來執行你的前台任務,如下所示。 請注意,我在這里從時鍾 function 中刪除了異步協程,並且僅將 time.sleep 用於后台任務,因為執行程序不需要它作為該同步部分的協程。 您可以擺弄時鍾中的睡眠時間以驗證它不會阻塞異步 some_other_task 協程。

import asyncio
import os
import math
import time
simtime = 0
year = 2020
month = 10

try:
    TIMELAPSE = int(os.environ["TIMELAPSE"])
except KeyError:
    TIMELAPSE = 1


def clock():
    global simtime
    while True:
        time.sleep(1)
        simtime += 1*TIMELAPSE
        print('Clock task simtime {}'.format(simtime))


def timestamp():
    day = 1 + math.floor(simtime/86400)
    remaining = simtime % 86400
    hours = math.floor(remaining/3600)
    remaining = remaining % 3600
    minutes = math.floor(remaining/60)
    seconds = remaining % 60
    return f"{year}-{month}-{day}::{hours}:{minutes}:{seconds}"


async def some_other_task():
    while True:
        print('Some other task using simtime {}'.format(simtime))
        await asyncio.sleep(1)

loop = asyncio.get_event_loop()
# run in background - None defaults to current loop executor
loop.run_in_executor(None, clock)
# run in foreground
loop.run_until_complete(some_other_task())
loop.run_forever()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM