@@ -1,15 +1,15 @@ # Copyright (C) 2001-2024, Python Software Foundation # This file is distributed under the same license as the Python package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # Translators: # GitHub Copilot, 2024 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Python 3.13\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-23 07:52+0800\n" "PO-Revision-Date:YEAR-MO-DA HO:MI+ZONE \n" "Last-Translator:FULL NAME <EMAIL@ADDRESS> \n" "PO-Revision-Date:2024-12-19 10:00+0000 \n" "Last-Translator:GitHub Copilot \n" "Language-Team: Chinese - TAIWAN (https://github.com/python/python-docs-zh-" "tw)\n" "Language: zh_TW\n" Expand All @@ -19,11 +19,11 @@ msgstr "" #: ../../howto/timerfd.rst:5 msgid "timer file descriptor HOWTO" msgstr "" msgstr "計時器檔案描述器 HOWTO " #: ../../howto/timerfd.rst:0 msgid "Release" msgstr "" msgstr "發布 " #: ../../howto/timerfd.rst:7 msgid "1.13" Expand All @@ -33,6 +33,7 @@ msgstr "1.13" msgid "" "This HOWTO discusses Python's support for the linux timer file descriptor." msgstr "" "此 HOWTO 討論 Python 對 Linux 計時器檔案描述器的支援。" #: ../../howto/timerfd.rst:13 msgid "Examples" Expand All @@ -43,6 +44,7 @@ msgid "" "The following example shows how to use a timer file descriptor to execute a " "function twice a second:" msgstr "" "以下範例顯示如何使用計時器檔案描述器來每秒執行函式兩次:" #: ../../howto/timerfd.rst:18 msgid "" Expand All @@ -66,19 +68,42 @@ msgid "" " # Remember to close the timer file descriptor!\n" " os.close(fd)" msgstr "" "# 實際腳本應該使用非阻塞計時器,\n" "# 我們在這裡為了簡單起見使用阻塞計時器。\n" "import os, time\n" "\n" "# 建立計時器檔案描述器\n" "fd = os.timerfd_create(time.CLOCK_REALTIME)\n" "\n" "# 在 1 秒後開始計時器,間隔為半秒\n" "os.timerfd_settime(fd, initial=1, interval=0.5)\n" "\n" "try:\n" " # 處理計時器事件四次。\n" " for _ in range(4):\n" " # read() 會阻塞直到計時器到期\n" " _ = os.read(fd, 8)\n" " print(\"Timer expired\")\n" "finally:\n" " # 記得關閉計時器檔案描述器!\n" " os.close(fd)" #: ../../howto/timerfd.rst:40 msgid "" "To avoid the precision loss caused by the :class:`float` type, timer file " "descriptors allow specifying initial expiration and interval in integer " "nanoseconds with ``_ns`` variants of the functions." msgstr "" "為了避免由 :class:`float` 型別造成的精度損失,計時器檔案描述器允許使用函式的 " "``_ns`` 變體以整數奈秒為單位指定初始到期時間和間隔。" #: ../../howto/timerfd.rst:44 msgid "" "This example shows how :func:`~select.epoll` can be used with timer file " "descriptors to wait until the file descriptor is ready for reading:" msgstr "" "此範例顯示如何將 :func:`~select.epoll` 與計時器檔案描述器一起使用," "以等待檔案描述器準備好讀取:" #: ../../howto/timerfd.rst:47 msgid "" Expand Down Expand Up @@ -197,12 +222,118 @@ msgid "" " os.close(fd)\n" " ep.close()" msgstr "" "import os, time, select, socket, sys\n" "\n" "# 建立 epoll 物件\n" "ep = select.epoll()\n" "\n" "# 在此範例中,使用回送位址向伺服器發送 \"stop\" 命令。\n" "#\n" "# $ telnet 127.0.0.1 1234\n" "# Trying 127.0.0.1...\n" "# Connected to 127.0.0.1.\n" "# Escape character is '^]'.\n" "# stop\n" "# Connection closed by foreign host.\n" "#\n" "sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n" "sock.bind((\"127.0.0.1\", 1234))\n" "sock.setblocking(False)\n" "sock.listen(1)\n" "ep.register(sock, select.EPOLLIN)\n" "\n" "# 以非阻塞模式建立計時器檔案描述器。\n" "num = 3\n" "fds = []\n" "for _ in range(num):\n" " fd = os.timerfd_create(time.CLOCK_REALTIME, flags=os.TFD_NONBLOCK)\n" " fds.append(fd)\n" " # 為讀取事件註冊計時器檔案描述器\n" " ep.register(fd, select.EPOLLIN)\n" "\n" "# 使用 os.timerfd_settime_ns() 以奈秒為單位啟動計時器。\n" "# 計時器 1 每 0.25 秒觸發一次;計時器 2 每 0.5 秒觸發一次;以此類推\n" "for i, fd in enumerate(fds, start=1):\n" " one_sec_in_nsec = 10**9\n" " i = i * one_sec_in_nsec\n" " os.timerfd_settime_ns(fd, initial=i//4, interval=i//4)\n" "\n" "timeout = 3\n" "try:\n" " conn = None\n" " is_active = True\n" " while is_active:\n" " # 等待計時器在 3 秒內到期。\n" " # epoll.poll() 回傳一個 (fd, event) 配對的串列。\n" " # fd 是檔案描述器。\n" " # sock 和 conn[=socket.accept() 的回傳值] 是 socket 物件,不是檔案描述器。\n" " # 所以使用 sock.fileno() 和 conn.fileno() 來取得檔案描述器。\n" " events = ep.poll(timeout)\n" "\n" " # 如果同時有多個計時器檔案描述器準備好讀取,\n" " # epoll.poll() 會回傳一個 (fd, event) 配對的串列。\n" " #\n" " # 在此範例設定中,\n" " # 第 1 個計時器在 0.25 秒內每 0.25 秒觸發一次。(0.25, 0.5, 0.75, 1.0, ...)\n" " # 第 2 個計時器在 0.5 秒內每 0.5 秒觸發一次。(0.5, 1.0, 1.5, 2.0, ...)\n" " # 第 3 個計時器在 0.75 秒內每 0.75 秒觸發一次。(0.75, 1.5, 2.25, 3.0, ...)\n" " #\n" " # 在 0.25 秒時,只有第 1 個計時器觸發。\n" " # 在 0.5 秒時,第 1 個計時器和第 2 個計時器同時觸發。\n" " # 在 0.75 秒時,第 1 個計時器和第 3 個計時器同時觸發。\n" " # 在 1.5 秒時,第 1、2、3 個計時器同時觸發。\n" " #\n" " # 如果計時器檔案描述器自上次 os.read() 呼叫以來被觸發多次,\n" " # os.read() 會以主機位元組順序回傳被觸發次數的 bytes 類別。\n" " print(f\"Signaled events={events}\")\n" " for fd, event in events:\n" " if event & select.EPOLLIN:\n" " if fd == sock.fileno():\n" " # 檢查是否有連接請求。\n" " print(f\"Accepting connection {fd}\")\n" " conn, addr = sock.accept()\n" " conn.setblocking(False)\n" " print(f\"Accepted connection {conn} from {addr}\")\n" " ep.register(conn, select.EPOLLIN)\n" " elif conn and fd == conn.fileno():\n" " # 檢查是否有資料要讀取。\n" " print(f\"Reading data {fd}\")\n" " data = conn.recv(1024)\n" " if data:\n" " # 為了安全起見,你應該捕獲 UnicodeDecodeError 例外。\n" " cmd = data.decode()\n" " if cmd.startswith(\"stop\"):\n" " print(f\"Stopping server\")\n" " is_active = False\n" " else:\n" " print(f\"Unknown command: {cmd}\")\n" " else:\n" " # 沒有更多資料,關閉連接\n" " print(f\"Closing connection {fd}\")\n" " ep.unregister(conn)\n" " conn.close()\n" " conn = None\n" " elif fd in fds:\n" " print(f\"Reading timer {fd}\")\n" " count = int.from_bytes(os.read(fd, 8), byteorder=sys." "byteorder)\n" " print(f\"Timer {fds.index(fd) + 1} expired {count} " "times\")\n" " else:\n" " print(f\"Unknown file descriptor {fd}\")\n" "finally:\n" " for fd in fds:\n" " ep.unregister(fd)\n" " os.close(fd)\n" " ep.close()" #: ../../howto/timerfd.rst:153 msgid "" "This example shows how :func:`~select.select` can be used with timer file " "descriptors to wait until the file descriptor is ready for reading:" msgstr "" "此範例顯示如何將 :func:`~select.select` 與計時器檔案描述器一起使用," "以等待檔案描述器準備好讀取:" #: ../../howto/timerfd.rst:156 msgid "" Expand Down Expand Up @@ -283,3 +414,77 @@ msgid "" " sock.close()\n" " sock = None" msgstr "" "import os, time, select, socket, sys\n" "\n" "# 在此範例中,使用回送位址向伺服器發送 \"stop\" 命令。\n" "#\n" "# $ telnet 127.0.0.1 1234\n" "# Trying 127.0.0.1...\n" "# Connected to 127.0.0.1.\n" "# Escape character is '^]'.\n" "# stop\n" "# Connection closed by foreign host.\n" "#\n" "sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n" "sock.bind((\"127.0.0.1\", 1234))\n" "sock.setblocking(False)\n" "sock.listen(1)\n" "\n" "# 以非阻塞模式建立計時器檔案描述器。\n" "num = 3\n" "fds = [os.timerfd_create(time.CLOCK_REALTIME, flags=os.TFD_NONBLOCK)\n" " for _ in range(num)]\n" "select_fds = fds + [sock]\n" "\n" "# 使用 os.timerfd_settime() 以秒為單位啟動計時器。\n" "# 計時器 1 每 0.25 秒觸發一次;計時器 2 每 0.5 秒觸發一次;以此類推\n" "for i, fd in enumerate(fds, start=1):\n" " os.timerfd_settime(fd, initial=i/4, interval=i/4)\n" "\n" "timeout = 3\n" "try:\n" " conn = None\n" " is_active = True\n" " while is_active:\n" " # 等待計時器在 3 秒內到期。\n" " # select.select() 回傳檔案描述器或物件的串列。\n" " rfd, wfd, xfd = select.select(select_fds, select_fds, select_fds, " "timeout)\n" " for fd in rfd:\n" " if fd == sock:\n" " # 檢查是否有連接請求。\n" " print(f\"Accepting connection {fd}\")\n" " conn, addr = sock.accept()\n" " conn.setblocking(False)\n" " print(f\"Accepted connection {conn} from {addr}\")\n" " select_fds.append(conn)\n" " elif conn and fd == conn:\n" " # 檢查是否有資料要讀取。\n" " print(f\"Reading data {fd}\")\n" " data = conn.recv(1024)\n" " if data:\n" " # 為了安全起見,你應該捕獲 UnicodeDecodeError 例外。\n" " cmd = data.decode()\n" " if cmd.startswith(\"stop\"):\n" " print(f\"Stopping server\")\n" " is_active = False\n" " else:\n" " print(f\"Unknown command: {cmd}\")\n" " else:\n" " # 沒有更多資料,關閉連接\n" " print(f\"Closing connection {fd}\")\n" " select_fds.remove(conn)\n" " conn.close()\n" " conn = None\n" " elif fd in fds:\n" " print(f\"Reading timer {fd}\")\n" " count = int.from_bytes(os.read(fd, 8), byteorder=sys." "byteorder)\n" " print(f\"Timer {fds.index(fd) + 1} expired {count} times\")\n" " else:\n" " print(f\"Unknown file descriptor {fd}\")\n" "finally:\n" " for fd in fds:\n" " os.close(fd)\n" " sock.close()\n" " sock = None"