11# Copyright (C) 2001-2024, Python Software Foundation
22# This file is distributed under the same license as the Python package.
3- # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
3+ # Translators:
4+ # GitHub Copilot, 2024
45#
5- #, fuzzy
66msgid ""
77msgstr ""
88"Project-Id-Version : Python 3.13\n "
99"Report-Msgid-Bugs-To : \n "
1010"POT-Creation-Date : 2024-09-23 07:52+0800\n "
11- "PO-Revision-Date : YEAR-MO-DA HO:MI+ZONE \n "
12- "Last-Translator : FULL NAME <EMAIL@ADDRESS> \n "
11+ "PO-Revision-Date : 2024-12-19 10:00+0000 \n "
12+ "Last-Translator : GitHub Copilot \n "
1313"Language-Team : Chinese - TAIWAN (https://github.com/python/python-docs-zh- "
1414"tw)\n "
1515"Language : zh_TW\n "
@@ -19,11 +19,11 @@ msgstr ""
1919
2020#: ../../howto/timerfd.rst:5
2121msgid "timer file descriptor HOWTO"
22- msgstr ""
22+ msgstr "計時器檔案描述器 HOWTO "
2323
2424#: ../../howto/timerfd.rst:0
2525msgid "Release"
26- msgstr ""
26+ msgstr "發布 "
2727
2828#: ../../howto/timerfd.rst:7
2929msgid "1.13"
@@ -33,6 +33,7 @@ msgstr "1.13"
3333msgid ""
3434"This HOWTO discusses Python's support for the linux timer file descriptor."
3535msgstr ""
36+ "此 HOWTO 討論 Python 對 Linux 計時器檔案描述器的支援。"
3637
3738#: ../../howto/timerfd.rst:13
3839msgid "Examples"
@@ -43,6 +44,7 @@ msgid ""
4344"The following example shows how to use a timer file descriptor to execute a "
4445"function twice a second:"
4546msgstr ""
47+ "以下範例顯示如何使用計時器檔案描述器來每秒執行函式兩次:"
4648
4749#: ../../howto/timerfd.rst:18
4850msgid ""
@@ -66,19 +68,42 @@ msgid ""
6668" # Remember to close the timer file descriptor!\n"
6769" os.close(fd)"
6870msgstr ""
71+ "# 實際腳本應該使用非阻塞計時器,\n"
72+ "# 我們���這裡為了簡單起見使用阻塞計時器。\n"
73+ "import os, time\n"
74+ "\n"
75+ "# 建立計時器檔案描述器\n"
76+ "fd = os.timerfd_create(time.CLOCK_REALTIME)\n"
77+ "\n"
78+ "# 在 1 秒後開始計時器,間隔為半秒\n"
79+ "os.timerfd_settime(fd, initial=1, interval=0.5)\n"
80+ "\n"
81+ "try:\n"
82+ " # 處理計時器事件四次。\n"
83+ " for _ in range(4):\n"
84+ " # read() 會阻塞直到計時器到期\n"
85+ " _ = os.read(fd, 8)\n"
86+ " print(\" Timer expired\" )\n"
87+ "finally:\n"
88+ " # 記得關閉計時器檔案描述器!\n"
89+ " os.close(fd)"
6990
7091#: ../../howto/timerfd.rst:40
7192msgid ""
7293"To avoid the precision loss caused by the :class:`float` type, timer file "
7394"descriptors allow specifying initial expiration and interval in integer "
7495"nanoseconds with ``_ns`` variants of the functions."
7596msgstr ""
97+ "為了避免由 :class:`float` 型別造成的精度損失,計時器檔案描述器允許使用函式的 "
98+ "``_ns`` 變體以整數奈���為單位指定初始到期時間和間隔。"
7699
77100#: ../../howto/timerfd.rst:44
78101msgid ""
79102"This example shows how :func:`~select.epoll` can be used with timer file "
80103"descriptors to wait until the file descriptor is ready for reading:"
81104msgstr ""
105+ "此範例顯示如何將 :func:`~select.epoll` 與計時器檔案描述器一起使用,"
106+ "以等待檔案描述器準備好讀取:"
82107
83108#: ../../howto/timerfd.rst:47
84109msgid ""
@@ -197,12 +222,118 @@ msgid ""
197222" os.close(fd)\n"
198223" ep.close()"
199224msgstr ""
225+ "import os, time, select, socket, sys\n"
226+ "\n"
227+ "# 建立 epoll 物件\n"
228+ "ep = select.epoll()\n"
229+ "\n"
230+ "# 在此範例中,使用回送位址向伺服器發送 \" stop\" 命令。\n"
231+ "#\n"
232+ "# $ telnet 127.0.0.1 1234\n"
233+ "# Trying 127.0.0.1...\n"
234+ "# Connected to 127.0.0.1.\n"
235+ "# Escape character is '^]'.\n"
236+ "# stop\n"
237+ "# Connection closed by foreign host.\n"
238+ "#\n"
239+ "sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n"
240+ "sock.bind((\" 127.0.0.1\" , 1234))\n"
241+ "sock.setblocking(False)\n"
242+ "sock.listen(1)\n"
243+ "ep.register(sock, select.EPOLLIN)\n"
244+ "\n"
245+ "# 以非阻塞模式建立計時器檔案描述器。\n"
246+ "num = 3\n"
247+ "fds = []\n"
248+ "for _ in range(num):\n"
249+ " fd = os.timerfd_create(time.CLOCK_REALTIME, flags=os.TFD_NONBLOCK)\n"
250+ " fds.append(fd)\n"
251+ " # 為讀取事件註冊計時器檔案描述器\n"
252+ " ep.register(fd, select.EPOLLIN)\n"
253+ "\n"
254+ "# 使用 os.timerfd_settime_ns() 以奈秒為單位啟動計時器。\n"
255+ "# 計時器 1 每 0.25 秒觸發一次;計時器 2 每 0.5 秒觸發一次;以此類推\n"
256+ "for i, fd in enumerate(fds, start=1):\n"
257+ " one_sec_in_nsec = 10**9\n"
258+ " i = i * one_sec_in_nsec\n"
259+ " os.timerfd_settime_ns(fd, initial=i//4, interval=i//4)\n"
260+ "\n"
261+ "timeout = 3\n"
262+ "try:\n"
263+ " conn = None\n"
264+ " is_active = True\n"
265+ " while is_active:\n"
266+ " # 等待計時器在 3 秒內到期。\n"
267+ " # epoll.poll() 回傳一個 (fd, event) 配對的串列。\n"
268+ " # fd 是檔案描述器。\n"
269+ " # sock 和 conn[=socket.accept() 的回傳值] 是 socket 物件,不是檔案描述器。\n"
270+ " # 所以使用 sock.fileno() 和 conn.fileno() 來取得檔案描述器。\n"
271+ " events = ep.poll(timeout)\n"
272+ "\n"
273+ " # 如果同時有多個計時器檔案描述器準備好讀取,\n"
274+ " # epoll.poll() 會回傳一個 (fd, event) 配對的串列。\n"
275+ " #\n"
276+ " # 在此範例設定中,\n"
277+ " # 第 1 個計時器在 0.25 秒內每 0.25 秒觸發一次。(0.25, 0.5, 0.75, 1.0, ...)\n"
278+ " # 第 2 個計時器在 0.5 秒內每 0.5 秒觸發一次。(0.5, 1.0, 1.5, 2.0, ...)\n"
279+ " # 第 3 個計時器在 0.75 秒內每 0.75 秒觸發一次。(0.75, 1.5, 2.25, 3.0, ...)\n"
280+ " #\n"
281+ " # 在 0.25 秒時,只有第 1 個計時器觸發。\n"
282+ " # 在 0.5 秒時,第 1 個計時器和第 2 個計時器同時觸發。\n"
283+ " # 在 0.75 秒時,第 1 個計時器和第 3 個計時器同時觸發。\n"
284+ " # 在 1.5 秒時,第 1、2、3 個計時器同時觸發。\n"
285+ " #\n"
286+ " # 如果計時器檔案描述器自上次 os.read() 呼叫以來被觸發多次,\n"
287+ " # os.read() 會以主機位元組順序回傳被觸發次數的 bytes 類別。\n"
288+ " print(f\" Signaled events={events}\" )\n"
289+ " for fd, event in events:\n"
290+ " if event & select.EPOLLIN:\n"
291+ " if fd == sock.fileno():\n"
292+ " # 檢查是否有連接請求。\n"
293+ " print(f\" Accepting connection {fd}\" )\n"
294+ " conn, addr = sock.accept()\n"
295+ " conn.setblocking(False)\n"
296+ " print(f\" Accepted connection {conn} from {addr}\" )\n"
297+ " ep.register(conn, select.EPOLLIN)\n"
298+ " elif conn and fd == conn.fileno():\n"
299+ " # 檢查是否有資料要讀取。\n"
300+ " print(f\" Reading data {fd}\" )\n"
301+ " data = conn.recv(1024)\n"
302+ " if data:\n"
303+ " # 為了安全起見,你應該捕獲 UnicodeDecodeError 例外。\n"
304+ " cmd = data.decode()\n"
305+ " if cmd.startswith(\" stop\" ):\n"
306+ " print(f\" Stopping server\" )\n"
307+ " is_active = False\n"
308+ " else:\n"
309+ " print(f\" Unknown command: {cmd}\" )\n"
310+ " else:\n"
311+ " # 沒有更多資料,關閉連接\n"
312+ " print(f\" Closing connection {fd}\" )\n"
313+ " ep.unregister(conn)\n"
314+ " conn.close()\n"
315+ " conn = None\n"
316+ " elif fd in fds:\n"
317+ " print(f\" Reading timer {fd}\" )\n"
318+ " count = int.from_bytes(os.read(fd, 8), byteorder=sys."
319+ "byteorder)\n"
320+ " print(f\" Timer {fds.index(fd) + 1} expired {count} "
321+ "times\" )\n"
322+ " else:\n"
323+ " print(f\" Unknown file descriptor {fd}\" )\n"
324+ "finally:\n"
325+ " for fd in fds:\n"
326+ " ep.unregister(fd)\n"
327+ " os.close(fd)\n"
328+ " ep.close()"
200329
201330#: ../../howto/timerfd.rst:153
202331msgid ""
203332"This example shows how :func:`~select.select` can be used with timer file "
204333"descriptors to wait until the file descriptor is ready for reading:"
205334msgstr ""
335+ "此範例顯示如何將 :func:`~select.select` 與計時器檔案描述器一起使用,"
336+ "以等待檔案描述器準備好讀取:"
206337
207338#: ../../howto/timerfd.rst:156
208339msgid ""
@@ -283,3 +414,77 @@ msgid ""
283414" sock.close()\n"
284415" sock = None"
285416msgstr ""
417+ "import os, time, select, socket, sys\n"
418+ "\n"
419+ "# 在此範例中,使用回送位址向伺服器發送 \" stop\" 命令。\n"
420+ "#\n"
421+ "# $ telnet 127.0.0.1 1234\n"
422+ "# Trying 127.0.0.1...\n"
423+ "# Connected to 127.0.0.1.\n"
424+ "# Escape character is '^]'.\n"
425+ "# stop\n"
426+ "# Connection closed by foreign host.\n"
427+ "#\n"
428+ "sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n"
429+ "sock.bind((\" 127.0.0.1\" , 1234))\n"
430+ "sock.setblocking(False)\n"
431+ "sock.listen(1)\n"
432+ "\n"
433+ "# 以非阻塞模式建立計時器檔案描述器。\n"
434+ "num = 3\n"
435+ "fds = [os.timerfd_create(time.CLOCK_REALTIME, flags=os.TFD_NONBLOCK)\n"
436+ " for _ in range(num)]\n"
437+ "select_fds = fds + [sock]\n"
438+ "\n"
439+ "# 使用 os.timerfd_settime() 以秒為單位啟動計時器。\n"
440+ "# 計時器 1 每 0.25 秒觸發一次;計時器 2 每 0.5 秒觸發一次;以此類推\n"
441+ "for i, fd in enumerate(fds, start=1):\n"
442+ " os.timerfd_settime(fd, initial=i/4, interval=i/4)\n"
443+ "\n"
444+ "timeout = 3\n"
445+ "try:\n"
446+ " conn = None\n"
447+ " is_active = True\n"
448+ " while is_active:\n"
449+ " # 等待計時器在 3 秒內到期。\n"
450+ " # select.select() 回傳檔案描述器或物件的串列。\n"
451+ " rfd, wfd, xfd = select.select(select_fds, select_fds, select_fds, "
452+ "timeout)\n"
453+ " for fd in rfd:\n"
454+ " if fd == sock:\n"
455+ " # 檢查是否有連接請求。\n"
456+ " print(f\" Accepting connection {fd}\" )\n"
457+ " conn, addr = sock.accept()\n"
458+ " conn.setblocking(False)\n"
459+ " print(f\" Accepted connection {conn} from {addr}\" )\n"
460+ " select_fds.append(conn)\n"
461+ " elif conn and fd == conn:\n"
462+ " # 檢查是否有資料要讀取。\n"
463+ " print(f\" Reading data {fd}\" )\n"
464+ " data = conn.recv(1024)\n"
465+ " if data:\n"
466+ " # 為了安全起見,你應���捕獲 UnicodeDecodeError 例外。\n"
467+ " cmd = data.decode()\n"
468+ " if cmd.startswith(\" stop\" ):\n"
469+ " print(f\" Stopping server\" )\n"
470+ " is_active = False\n"
471+ " else:\n"
472+ " print(f\" Unknown command: {cmd}\" )\n"
473+ " else:\n"
474+ " # 沒有更多資料,關閉連接\n"
475+ " print(f\" Closing connection {fd}\" )\n"
476+ " select_fds.remove(conn)\n"
477+ " conn.close()\n"
478+ " conn = None\n"
479+ " elif fd in fds:\n"
480+ " print(f\" Reading timer {fd}\" )\n"
481+ " count = int.from_bytes(os.read(fd, 8), byteorder=sys."
482+ "byteorder)\n"
483+ " print(f\" Timer {fds.index(fd) + 1} expired {count} times\" )\n"
484+ " else:\n"
485+ " print(f\" Unknown file descriptor {fd}\" )\n"
486+ "finally:\n"
487+ " for fd in fds:\n"
488+ " os.close(fd)\n"
489+ " sock.close()\n"
490+ " sock = None"
0 commit comments