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