Thời gian UNIX được đo trên máy tính của bạn, chạy UNIX.
Câu trả lời này sẽ mong bạn biết được Giờ thế giới chung (UTC), Giờ nguyên tử quốc tế (TAI) và giây thứ hai là gì. Giải thích chúng vượt ra ngoài phạm vi của Unix và Linux Stack Exchange. Đây không phải là trao đổi ngăn xếp vật lý hoặc thiên văn.
Phần cứng
Máy tính của bạn chứa các bộ dao động khác nhau điều khiển đồng hồ và bộ hẹn giờ. Chính xác những gì nó đã thay đổi từ máy tính này sang máy tính khác tùy thuộc vào kiến trúc của nó. Nhưng thông thường, và trong điều khoản rất chung chung:
- Có một bộ định thời khoảng thời gian lập trình (PIT) ở đâu đó, có thể được lập trình để đếm một số dao động nhất định và kích hoạt ngắt đến bộ xử lý trung tâm.
- Có một bộ đếm chu kỳ trên bộ xử lý trung tâm chỉ đơn giản là đếm 1 cho mỗi chu kỳ lệnh được thực thi.
Lý thuyết hoạt động, theo nghĩa rất rộng
Nhân hệ điều hành sử dụng PIT để tạo ra các dấu tick . Nó thiết lập thuế TNCN để chạy tự do, đếm đúng số lượng dao động trong một khoảng thời gian, giả sử, một phần trăm giây, tạo ra một ngắt, sau đó tự động đặt lại số đếm để đi lại. Có các biến thể về điều này, nhưng về bản chất, điều này gây ra một ngắt đánh dấu được nâng lên với tần số cố định.
Trong phần mềm, kernel tăng một bộ đếm mỗi tích tắc. Nó biết tần số đánh dấu, bởi vì nó đã lập trình thuế TNCN ở vị trí đầu tiên. Vì vậy, nó biết có bao nhiêu tick tạo nên một giây. Nó có thể sử dụng điều này để biết khi nào tăng một bộ đếm đếm giây. Đây là ý tưởng của hạt nhân về "Thời gian UNIX". Thực tế, nó chỉ đơn giản là đếm ngược lên với tốc độ một trên mỗi giây SI nếu để lại các thiết bị của chính nó.
Bốn điều phức tạp này, mà tôi sẽ trình bày dưới dạng rất chung chung.
Phần cứng không hoàn hảo. Một PIT có bảng dữ liệu nói rằng nó có tần số dao động là N Hertz thay vào đó có tần số (giả sử) N .00002 Hertz, với các hậu quả rõ ràng.
Sơ đồ này tương tác rất kém với quản lý năng lượng, bởi vì CPU đang thức dậy hàng trăm lần mỗi giây để làm ít hơn là tăng một số trong một biến. Vì vậy, một số hệ điều hành có những gì được gọi là thiết kế "không có dấu vết". Thay vì làm cho PIT gửi một ngắt cho mỗi tick, kernel hoạt động (từ bộ lập lịch mức thấp) có bao nhiêu tick sẽ trôi qua mà không có lượng tử luồng nào, và lập trình PIT để tính cho nhiều tick đó vào tương lai trước khi phát hành một đánh dấu ngắt. Nó biết rằng sau đó nó phải ghi lại đoạn N tick ở lần ngắt tiếp theo, thay vì 1 tick.
Phần mềm ứng dụng có khả năng thay đổi thời gian hiện tại của kernel. Nó có thể bước giá trị hoặc nó có thể xoay giá trị. Slewing liên quan đến việc điều chỉnh số lượng bọ ve phải đi để tăng bộ đếm giây. Vì vậy, các giây truy cập không nhất thiết phải đếm theo tỷ lệ một trong mỗi SI thứ hai nào , thậm chí giả tạo dao động hoàn hảo. Bước bao gồm chỉ đơn giản là viết một số mới trong bộ đếm giây, điều này thường không xảy ra cho đến 1 SI giây kể từ giây cuối cùng được đánh dấu.
Hạt nhân hiện đại không chỉ đếm giây mà còn đếm nano giây. Nhưng thật nực cười và thường hoàn toàn không khả thi khi bị gián đoạn đánh dấu một lần trên mỗi nano giây. Đây là nơi mà những thứ như bộ đếm chu kỳ phát huy tác dụng. Hạt nhân ghi nhớ giá trị bộ đếm chu kỳ ở mỗi giây (hoặc tại mỗi tích tắc) và có thể hoạt động, từ giá trị hiện tại của bộ đếm khi có thứ gì đó muốn biết thời gian tính bằng nano giây, phải mất bao nhiêu nano giây kể từ giây cuối cùng (hoặc đánh dấu). Mặc dù vậy, một lần nữa, quản lý năng lượng và nhiệt đóng vai trò quan trọng vì tần số chu kỳ hướng dẫn có thể thay đổi, do đó, hạt nhân làm những việc như dựa vào phần cứng bổ sung như (giả sử) Bộ đếm thời gian chính xác cao (HPET).
Ngôn ngữ C và POSIX
Các thư viện chuẩn của ngôn ngữ C mô tả thời gian trong điều khoản của một loại đục, time_t
, một loại cấu trúc tm
với các lĩnh vực cụ thể khác nhau, và chức năng thư viện khác nhau như time()
, mktime()
, và localtime()
.
Tóm lại: bản thân ngôn ngữ C chỉ đảm bảo rằng đó time_t
là một trong những loại dữ liệu số có sẵn và cách duy nhất đáng tin cậy để tính chênh lệch thời gian là difftime()
hàm. Đó là tiêu chuẩn POSIX cung cấp các đảm bảo chặt chẽ hơn time_t
trên thực tế là một trong các loại số nguyên và nó tính số giây kể từ Kỷ nguyên . Nó cũng là tiêu chuẩn POSIX chỉ định timespec
loại cấu trúc.
Các time()
chức năng đôi khi được mô tả như một cuộc gọi hệ thống. Trên thực tế, ngày nay nó không phải là cuộc gọi hệ thống cơ bản trên nhiều hệ thống. Ví dụ, trên FreeBSD, cuộc gọi hệ thống cơ bản là clock_gettime()
, có nhiều "đồng hồ" khác nhau có sẵn tính bằng giây hoặc giây + nano giây theo nhiều cách khác nhau. Đây là hệ thống gọi phần mềm ứng dụng này đọc Thời gian UNIX từ kernel. (Cuộc clock_settime()
gọi hệ thống phù hợp cho phép họ thực hiện adjtime()
cuộc gọi và cuộc gọi hệ thống cho phép họ thực hiện cuộc gọi đó.)
Nhiều người vẫy tiêu chuẩn POSIX xung quanh với những tuyên bố rất chắc chắn và chính xác về những gì nó quy định. Những người như vậy, thường xuyên hơn không, không thực sự đọc tiêu chuẩn POSIX. Như lý do của nó đặt ra, ý tưởng đếm "giây kể từ Kỷ nguyên", đó là cụm từ mà tiêu chuẩn sử dụng, cố ý không xác định rằng POSIX giây có cùng độ dài với SI giây, cũng không phải là kết quả của gmtime()
"nhất thiết UTC, mặc dù xuất hiện ". Tiêu chuẩn POSIX là cố ýđủ lỏng để nó cho phép (nói) một hệ thống UNIX nơi người quản trị đi và tự sửa các bước điều chỉnh thứ hai bằng cách cài đặt lại đồng hồ vào tuần sau khi chúng xảy ra. Thật vậy, lý do chỉ ra rằng nó cố tình lỏng lẻo đủ để chứa các hệ thống mà đồng hồ đã bị cố tình đặt sai vào một thời điểm nào đó ngoài thời gian UTC hiện tại.
UTC và TAI
Việc giải thích Thời gian UNIX thu được từ kernel tùy thuộc vào thói quen của thư viện đang chạy trong các ứng dụng. POSIX chỉ định danh tính giữa thời gian của hạt nhân và "thời gian bị hỏng" trong a struct tm
. Nhưng, như Daniel J. Bernstein đã từng chỉ ra, phiên bản năm 1997 của tiêu chuẩn đã nhận dạng sai một cách đáng xấu hổ, làm xáo trộn quy tắc năm nhuận của Lịch Gregorian (điều mà học sinh học được) để tính toán bị lỗi từ năm 2100 trở đi. "Vinh dự hơn trong vi phạm hơn là tuân thủ" là một cụm từ dễ hiểu.
Và thực sự nó là. Một số hệ thống hiện nay dựa trên diễn giải thư viện này do Arthur David Olson viết, tham khảo "cơ sở dữ liệu múi giờ Olson" khét tiếng, thường được mã hóa trong các tệp cơ sở dữ liệu /usr/share/zoneinfo/
. Hệ thống Olson có hai chế độ:
- "Số giây kể từ Kỷ nguyên" của hạt nhân được coi là đếm giây UTC kể từ 1970-01-01 00:00:00 UTC, ngoại trừ giây nhuận. Điều này sử dụng
posix/
tập hợp các tệp cơ sở dữ liệu múi giờ Olson. Tất cả các ngày có 86400 giây hạt nhân và không bao giờ có 61 giây trong một phút, nhưng chúng không phải luôn luôn là độ dài của giây SI và đồng hồ hạt nhân cần xoay hoặc bước khi xảy ra bước nhảy vọt.
- "Số giây kể từ kỷ nguyên" của hạt nhân được coi là tính số giây TAI kể từ 1970-01-01 00:00:10 TAI. Điều này sử dụng
right/
tập hợp các tệp cơ sở dữ liệu múi giờ Olson. Kernel giây dài 1 SI giây và đồng hồ kernel không bao giờ cần xoay hoặc bước để điều chỉnh trong giây nhuận, nhưng thời gian bị hỏng có thể có các giá trị như 23:59:60 và ngày không phải luôn luôn dài 86400 giây.
M. Bernstein đã viết một số công cụ, bao gồm cả daemontools
bộ công cụ của mình , điều đó là cần thiết right/
bởi vì họ chỉ cần thêm 10 time_t
để có được TAI giây kể từ 1970-01-01 00:00:00 TAI. Ông đã ghi lại điều này trong trang hướng dẫn.
Yêu cầu này (có lẽ vô tình) được kế thừa bởi các bộ công cụ như daemontools-encore
và runit
và của Felix von Leitner libowfat
. Ví dụ, sử dụng Bernsteinmultilog
, Guentermultilog
hoặc Papesvlogd
với posix/
cấu hình Olson và tất cả các dấu thời gian TAI64N sẽ (tại thời điểm viết này) 26 giây sau số đếm TAI thực tế kể từ 1970-01-01 00:00:10 TAI.
Laurent Bercot và tôi đã giải quyết vấn đề này trong s6 và nosh, mặc dù chúng tôi đã thực hiện các phương pháp khác nhau. M. Bercot tai_from_sysclock()
dựa vào một lá cờ thời gian biên dịch. các công cụ nosh xử lý trong TAI64N xem xét các biến TZ
và TZDIR
môi trường để tự động phát hiện posix/
và right/
nếu chúng có thể.
Thật thú vị, các tài liệu time2posix()
và posix2time()
chức năng FreeBSD cho phép tương đương right/
với chế độ Olson với số time_t
giây TAI. Họ không rõ ràng được kích hoạt, tuy nhiên.
Một lần nữa…
Thời gian UNIX được đo trên máy tính của bạn chạy UNIX, bằng các bộ dao động có trong phần cứng máy tính của bạn. Nó không sử dụng SI giây; nó không phải là UTC mặc dù nó có thể rất giống với nó; và nó cố ý cho phép đồng hồ của bạn bị sai.
đọc thêm