เวลา UNIX ถูกวัดบนคอมพิวเตอร์ของคุณโดยใช้ UNIX
คำตอบนี้จะคาดหวังให้คุณทราบว่าCoördinated Universal Time (UTC) เวลาสากลอะตอม (TAI) และ SI วินาทีคืออะไร อธิบายได้ดีเกินขอบเขตของ Unix และ Linux Stack Exchange นี่ไม่ใช่การแลกเปลี่ยนทางฟิสิกส์หรือดาราศาสตร์
ฮาร์ดแวร์
คอมพิวเตอร์ของคุณมีออสซิลเลเตอร์หลายตัวที่ขับเคลื่อนนาฬิกาและตัวจับเวลา สิ่งที่แตกต่างจากคอมพิวเตอร์หนึ่งไปอีกเครื่องหนึ่งขึ้นอยู่กับสถาปัตยกรรมของมัน แต่โดยทั่วไปและในแง่ทั่วไปมาก:
- มีตัวจับเวลาช่วงเวลาที่ตั้งโปรแกรมได้ (PIT) ที่ใดที่หนึ่งซึ่งสามารถตั้งโปรแกรมให้นับจำนวนการแกว่งที่กำหนดและทริกเกอร์การขัดจังหวะหน่วยประมวลผลกลาง
- มีตัวนับรอบตัวประมวลผลกลางที่นับเพียง 1 สำหรับแต่ละรอบคำสั่งที่เรียกใช้งาน
ทฤษฎีการทำงานในแง่กว้างมาก
ทำให้ระบบปฏิบัติการเคอร์เนลใช้ PIT เพื่อสร้างเห็บ มันตั้งค่า PIT ให้ทำงานโดยอิสระนับจำนวนการแกว่งที่ถูกต้องสำหรับช่วงเวลาหนึ่งร้อยวินาทีสร้างการขัดจังหวะจากนั้นรีเซ็ตการนับอัตโนมัติอีกครั้ง มีการเปลี่ยนแปลงในเรื่องนี้ แต่ในสาระสำคัญนี้ทำให้เกิดการขัดจังหวะเห็บที่จะเพิ่มความถี่คงที่
ในซอฟต์แวร์เคอร์เนลจะเพิ่มตัวนับทุกเครื่องหมาย มันรู้ความถี่ของเห็บเพราะมันตั้งโปรแกรม PIT ตั้งแต่แรก ดังนั้นจึงรู้ว่ากี่เห็บทำขึ้นเป็นวินาที มันสามารถใช้สิ่งนี้เพื่อทราบว่าเมื่อใดที่จะเพิ่มตัวนับที่นับวินาที สิ่งนี้เป็นแนวคิดของเคอร์เนลของ "UNIX Time" ที่จริงแล้วมันก็นับขึ้นในอัตราหนึ่งต่อ SI วินาทีถ้าปล่อยให้อุปกรณ์ของตัวเอง
มีสี่สิ่งที่ทำให้เกิดความยุ่งยากซึ่งฉันจะนำเสนอในแง่ทั่วไป
ฮาร์ดแวร์ไม่สมบูรณ์ PIT ที่แผ่นข้อมูลบอกว่ามีความถี่ออสซิลเลเตอร์ที่Nเฮิรตซ์อาจมีความถี่ (พูด) N .00002 Nเฮิร์ตซโดยมีผลที่ชัดเจน
รูปแบบนี้ทำงานร่วมกันได้ไม่ดีนักกับการจัดการพลังงานเนื่องจาก CPU กำลังตื่นขึ้นหลายร้อยครั้งต่อวินาทีเพื่อเพิ่มจำนวนในตัวแปรเพียงเล็กน้อย ดังนั้นระบบปฏิบัติการบางระบบจึงมีสิ่งที่รู้กันว่าเป็น "การออกแบบที่ไร้ค่า" แทนที่จะทำให้ PIT ส่งสัญญาณขัดจังหวะสำหรับทุก ๆ ติ๊กเคอร์เนลจะทำงานออกมา (จากตัวกำหนดตารางเวลาระดับต่ำ) จำนวน ticks จะไปโดยไม่มีเธรดควอนตัมวิ่งออกมาและโปรแกรม PIT จะนับจำนวน ticks นั้นลงใน ในอนาคตก่อนที่จะออกการขัดจังหวะเห็บ มันรู้ว่ามันจะต้องบันทึกเนื้อเรื่องของN ticks ที่สัญญาณรบกวน tick ถัดไปแทนที่จะเป็น 1 tick
แอพพลิเคชั่นซอฟต์แวร์มีความสามารถในการเปลี่ยนเวลาปัจจุบันของเคอร์เนล มันสามารถก้าวมูลค่าหรือสามารถฆ่าค่า Slewing เกี่ยวข้องกับการปรับจำนวนติ๊กที่ต้องผ่านเพื่อเพิ่มตัวนับวินาที ดังนั้นตัวนับวินาทีไม่จำเป็นต้องนับในอัตราหนึ่งต่อ SI วินาทีอย่างไรก็ตามแม้จะสมมติว่าออสซิลเลเตอร์สมบูรณ์แบบ การเหยียบเกี่ยวข้องกับการเขียนหมายเลขใหม่ในตัวนับวินาทีซึ่งไม่เกิดขึ้นจนกว่าจะถึง 1 SI วินาทีตั้งแต่วินาทีที่ผ่านมา
เมล็ดพันธุ์สมัยใหม่ไม่เพียง แต่นับวินาทีเท่านั้น แต่ยังนับเป็นนาโนวินาทีด้วย แต่มันไร้สาระและมักจะไม่สามารถทำได้หากมีเห็บขัดจังหวะครั้งเดียวต่อนาโนวินาที นี่คือสิ่งที่รอบตัวนับเข้ามาเล่น เคอร์เนลจะจดจำค่าตัวนับรอบในแต่ละวินาที (หรือที่แต่ละเห็บ) และสามารถทำงานได้จากมูลค่าปัจจุบันของตัวนับเมื่อสิ่งที่ต้องการรู้เวลาเป็นนาโนวินาทีจำนวนนาโนวินาทีจะต้องผ่านไปตั้งแต่วินาทีสุดท้าย (หรือ ติ๊ก) แม้ว่าการจัดการพลังงานและความร้อนจะเกิดความเสียหายเนื่องจากความถี่ของวงจรการเรียนการสอนสามารถเปลี่ยนแปลงได้ดังนั้นเมล็ดจึงทำสิ่งต่าง ๆ เช่นพึ่งพาฮาร์ดแวร์เพิ่มเติมเช่น (พูด) High Precision Event Timer (HPET)
ภาษา C และ POSIX
ห้องสมุดมาตรฐานของภาษา C อธิบายเวลาในแง่ของชนิดทึบแสงtime_t
ชนิดโครงสร้างtm
ที่มีเขตข้อมูลที่ระบุต่างๆและฟังก์ชั่นห้องสมุดต่างๆเช่นtime()
, และmktime()
localtime()
โดยย่อ: ภาษา C เองนั้นรับประกันได้ว่าtime_t
เป็นหนึ่งในประเภทข้อมูลตัวเลขที่มีอยู่และวิธีที่เชื่อถือได้เพียงวิธีเดียวในการคำนวณความแตกต่างของเวลาคือdifftime()
ฟังก์ชัน มันเป็นมาตรฐาน POSIX ที่ให้การค้ำประกันที่เข้มงวดที่time_t
เป็นหนึ่งในความเป็นจริงของจำนวนเต็มชนิดและว่ามันนับวินาทีตั้งแต่ยุค นอกจากนี้ยังเป็นมาตรฐาน POSIX ที่ระบุtimespec
ประเภทโครงสร้าง
time()
ฟังก์ชั่นบางครั้งก็อธิบายว่าเป็นสายระบบ ในความเป็นจริงมันไม่ได้เรียกระบบพื้นฐานในหลาย ๆ ระบบเป็นเวลานานในปัจจุบัน บน FreeBSD ตัวอย่างเช่นการเรียกใช้ระบบพื้นฐานคือclock_gettime()
ซึ่งมี "นาฬิกา" ต่างๆที่มีอยู่ซึ่งวัดได้ในไม่กี่วินาทีหรือวินาที + นาโนวินาทีในรูปแบบต่างๆ เป็นการเรียกระบบนี้โดยที่แอพพลิเคชั่นซอฟต์แวร์อ่านเวลา UNIX จากเคอร์เนล (การclock_settime()
เรียกระบบที่ตรงกันช่วยให้พวกเขาก้าวและการadjtime()
เรียกระบบช่วยให้พวกเขาฆ่ามัน)
หลายคนโบกคลื่นมาตรฐาน POSIX ด้วยการเรียกร้องที่ชัดเจนและแน่นอนมากเกี่ยวกับสิ่งที่กำหนดไว้ คนดังกล่าวมีบ่อยกว่าไม่อ่าน POSIX มาตรฐาน ตามที่เหตุผลได้กำหนดไว้ความคิดในการนับ "วินาทีนับตั้งแต่ยุค" ซึ่งเป็นวลีที่ใช้มาตรฐานโดยเจตนาไม่ได้ระบุว่าวินาที POSIX มีความยาวเท่ากับ SI วินาทีหรือว่าผลลัพธ์ของgmtime()
"จำเป็น UTC แม้จะมีรูปลักษณ์ของมันก็ตาม " มาตรฐาน POSIX นั้นจงใจหลวมพอที่จะอนุญาตให้ (พูด) ระบบ UNIX ที่ผู้ดูแลระบบไปและแก้ไขการปรับค่าเผ่นวินาทีด้วยตนเองโดยตั้งค่านาฬิกาใหม่ในสัปดาห์หลังจากที่มันเกิดขึ้น แท้จริงแล้วเหตุผลนั้นชี้ให้เห็นว่ามันตั้งใจปล่อยให้มันเพียงพอที่จะรองรับระบบที่มีการตั้งค่านาฬิกาผิดเวลาในบางครั้งนอกเหนือจากเวลา UTC ปัจจุบัน
UTC และ TAI
การตีความ UNIX Time ที่ได้รับจากเคอร์เนลขึ้นอยู่กับรูทีนไลบรารีที่รันในแอ็พพลิเคชัน POSIX ระบุตัวตนในระหว่างช่วงเวลาของเคอร์เนลและ "เสียเวลาลง" struct tm
ในหนึ่ง แต่ตามที่ Daniel J. Bernstein เคยชี้ให้เห็นว่ามาตรฐานฉบับปี 1997 มีความเป็นตัวตนที่ผิดอย่างน่าละอายทำให้กฎระเบียบปีก้าวกระโดดของปฏิทินเกรโกเรียน (สิ่งที่เด็กนักเรียนเรียนรู้) เพื่อให้การคำนวณนั้นผิดพลาดตั้งแต่ปี 2100 เป็นต้นไป "มีเกียรติมากขึ้นในการฝ่าฝืนมากกว่าการปฏิบัติ" เป็นวลีที่มาพร้อมกับใจ
และแน่นอนมันเป็น หลายระบบในปัจจุบันฐานการตีความนี้เมื่อประจำห้องสมุดที่เขียนโดยอาร์เธอร์เดวิดโอลสันที่ปรึกษาที่น่าอับอาย "ฐานข้อมูลเขตโอลสัน" /usr/share/zoneinfo/
มักจะเข้ารหัสในไฟล์ฐานข้อมูลภายใต้ ระบบ Olson มีสองโหมด:
- เคอร์เนล "วินาทีตั้งแต่ยุค" ถือเป็นนับวินาที UTC ตั้งแต่ 1970-01-01 00:00:00 UTC ยกเว้นวินาทีกระโดด ใช้
posix/
ชุดของไฟล์ฐานข้อมูลเขตเวลาของ Olson ทุกวันมีเคอร์เนล 86400 วินาทีและไม่เคยมี 61 วินาทีในหนึ่งนาที แต่ก็ไม่ได้มีความยาวของ SI วินาทีเสมอไปและนาฬิกาเคอร์เนลต้องการการแกว่งหรือก้าวเมื่อวินาทีกระโดดเกิดขึ้น
- เคอร์เนล "วินาทีนับตั้งแต่ยุค" ถือเป็นนับวินาที TAI ตั้งแต่ 1970-01-01 00:00:10 TAI ใช้
right/
ชุดของไฟล์ฐานข้อมูลเขตเวลาของ Olson Kernel วินาทีมีความยาว 1 SI วินาทีและนาฬิกาเคอร์เนลไม่ต้องการการแกว่งหรือก้าวเพื่อปรับวินาทีสำหรับ leap วินาที แต่เวลาที่แตกสลายอาจมีค่าเช่น 23:59:60 และวันไม่ยาว 86400 วินาทีเคอร์เนล
M. Bernstein เขียนเครื่องมือหลายอย่างรวมถึงdaemontools
ชุดเครื่องมือของเขาที่ต้องการright/
เพราะพวกเขาเพียงแค่เพิ่ม 10 ถึงtime_t
จะได้รับ TAI วินาทีตั้งแต่ 1970-01-01 00:00:00 TAI เขาบันทึกไว้ในหน้าคู่มือ
ความต้องการนี้ได้ (อาจไม่รู้) สืบทอดโดย toolsets เช่นdaemontools-encore
และrunit
และเฟลิกซ์ฟอน libowfat
Leitner ใช้Bernsteinmultilog
, Guentermultilog
หรือPape ที่svlogd
มีการposix/
กำหนดค่าแบบOlson และไทม์สแต็กของ TAI64N ทั้งหมดจะเป็น (ในขณะที่เขียนนี้) 26 วินาทีหลังการนับ TAI จริงนับตั้งแต่วินาทีที่ 1970-01-01 00:00:10 TAI
Laurent Bercot และฉันพูดถึงเรื่องนี้ใน s6 และ nosh แม้ว่าเราจะใช้วิธีการที่แตกต่างกัน M. Bercot tai_from_sysclock()
อาศัยธงเวลารวบรวม เครื่องมือ nosh ที่จัดการใน TAI64N ดูที่TZ
และTZDIR
ตัวแปรสภาพแวดล้อมเพื่อตรวจจับอัตโนมัติposix/
และright/
หากทำได้
ที่น่าสนใจคือเอกสาร FreeBSD time2posix()
และposix2time()
ฟังก์ชั่นที่อนุญาตให้เทียบเท่ากับright/
โหมดOlson ด้วยtime_t
TAI วินาที ดูเหมือนว่าจะไม่เปิดใช้งานอย่างไรก็ตาม
อีกครั้ง ...
เวลา UNIX ถูกวัดบนคอมพิวเตอร์ของคุณที่รัน UNIX โดย oscillators ที่อยู่ในฮาร์ดแวร์ของคอมพิวเตอร์ของคุณ ไม่ใช้ SI วินาที มันไม่ได้เป็น UTC แม้ว่ามันอาจจะดูคล้าย ๆ เผินๆก็ตาม และจงใจอนุญาตให้นาฬิกาของคุณผิด
อ่านเพิ่มเติม