เมื่อซอฟต์แวร์ถูกเรียกใช้งานในคอมพิวเตอร์นั้น คอมพิวเตอร์ไม่ได้เอาซอฟต์แวร์ทั้งตัวใส่ไว้ในหน่วยความจำเพื่อทำงาน แต่จะประมวลผลเฉพาะส่วนที่ต้องใช้งานในขณะนั้นเท่านั้น ส่วนของซอฟต์แวร์ดังกล่าวเราเรียกว่า โปรเซส (process) โดยอาจจะเป็นงานเดียว (task) หรือแบ่งย่อยงานออกเป็นหลายๆส่วน (thread) ซอฟต์แวร์แต่ละตัวอาจจะก่อให้เกิดโปรเซสเดียวหรือหลายโปรเซสก็ได้ โปรเซสแต่ละตัวอาจจะทำงานด้วยกันกับโปรเซสอื่นก็ได้ โปรเซสต้องใช้ทรัพยากรของเครื่อง เช่น หน่วยความจำ cpu และอุปกรณ์ต่อพ่วงต่างๆ โดยมีระบบปฏิบัติการเป็นคนจัดสรรทรัพยากรต่างๆให้กับโปรเซส
ภาพแสดงการใช้งานโปรเซส
โปรเซสมีทั้งแบบที่ทำงานให้เราเห็น ( run as foreground) เช่น หน้าจอคอนโซลก็เป็นโปรเซสชนิดหนึ่งที่คอยรับคำสั่งและโต้ตอบกับเรา บางโปรเซสก็ทำงานอยู่เบื้องหลัง (run as background) โดยที่เราไม่รู้เลยว่ามันทำงานอยู่ โปรเซสมีหลายชนิดตามลักษณะการทำงานของมันดังนี้
- Interactive Processes เป็นโปรเซสที่ผู้ใช้งานต้องเรียกมาใช้งานไม่ว่าจะเรียกผ่าน command line หรือ GUI หรือ เมนู ก็ตาม เช่น bash, firefox, top
- Batch Processes เป็นโปรเซสที่ทำงานอัติโนมัติตามลำดับคำสั่งที่กำหนดไว้ (scheduled) และไม่ได้ทำงานในหน้าต่างคอนโซลให้เราเห็น (run as background) เช่น updatedb (เป็นแบชที่คอยปรับปรุงฐานข้อมูลที่เก็บโครงสร้างไดเร็คทอรี่และไฟล์)
- Daemons เป็นโปรเซสที่ถูกเรียกใช้งานตั้งแต่เปิดเครื่องเพื่อคอยให้บริการเมื่อมีการร้องขอ เช่น httpd (คอยส่งหน้าเว็บให้ผู้ที่มาขอ), xinetd (คอยดูการเชื่อมต่อผ่านอินเตอร์เนตและเรียกใช้งาน daemon ที่เหมาะสมเพื่อให้บริการตามคำขอ)
- Threads เป็นงานย่อยๆของ task ของโปรเซส เช่น firefox, gnome-terminal-server
- Kernel Threads เป็นงานย่อยๆของเคอร์เนล เช่น kthreadd, ksoftirqd
ฟังก์ชั่นที่สำคัญของเคอร์เนลที่ใช้ในการจัดการคิวในการ run process ใน CPU คือฟังก์ชั่น schedule โดยฟังก์ชั่น schedule จะจัดการเอาโปรเซสเข้าหรือออกจาก CPU ตามลำดับความสำคัญและเวลาที่จะใช้ CPU โปรเซสแต่ละตัวจะมีสถานะต่างๆกันไปโดยสถานะสำคัญที่ควรรู้จักคือ
- Running state หมายถึงโปรเซสกำลังทำงานอยู่ใน CPU หรือรอให้ CPU ว่าง (time slice) อยู่ โปรเซสที่มีสถานะนี้จะอยู่ในคิวงาน (run queue) ของ CPU สำหรับเครื่องที่ CPU มีหลายคอร์แต่ละคอร์จะมีคิวของมันเอง
- บางครั้งโปรเซสก็อยู่ในสภาวะหลับ (sleep stage) หรือ คอย (waiting stage) เพื่อรออะไรบางอย่างที่จะมาปลุกมันเพื่อทำงาน เช่น รอรับคำสั่งจากผู้ใช้งานเป็นต้น
- บางครั้งโปรเซสก็หยุดทำงานแบบผิดปรกติและค้างอยู่ เราเรียกว่าซอมบี้ (zombie state)
ภาพแสดงการใช้งานฟังก์ชั่น schedule
เพื่อให้สามารถจัดการโปรเซสได้ระบบปฏิบัติการจะกำหนดหมายเลขประจำตัวให้กับแต่ละโปรเซสเรียกว่า PID (Process ID) โดยระบบปฏิบัติการจะใช้ PID ในการติดตามสถานะ การใช้ทรัพยากร และอื่นๆของโปรเซส เลข PID จะถูกนับต่อกันไปเรื่อยๆเริ่มจากโปรเซส init ที่ PID = 1 เนื่องจากเป็นโปรเซสแรกตั้งแต่เปิดเครื่องขึ้นมา นอกจาก PID ที่กล่าวมาแล้ว แล้วยังมี PID อีก 2 แบบคือ PPID (Parent PID) และ Thread ID
PPID (Parent PID) หมายถึงโปรเซสที่เรียกใช้โปรเซสตัวที่กำลังทำงานอยู่ ซึ่งถ้าโปรเซสที่เป็น parent ตายโปรเซสที่ถูกเรียกก็ต้องเลิกการทำงานด้วย ส่วน Thread ID คืองานย่อยๆของโปรเซสที่ทำงานใน CPU สำหรับโปรเซสที่มี thread เดียว Thread ID จะเหมือนกับ PID แต่ถ้าโปรเซสมีมากกว่า 1 thread แต่ละ thread จะมี thread id ของตัวเอง และแชร์ใช้ PID ด้วยกัน
บางครั้งซอฟต์แวร์ที่เราใช้งานเกิดอาการแฮงค์ เราอาจจะต้องยกเลิกโปรเซสของมันซึ่งทำได้โดยใช้คำสั่ง kill -SIGKILL pid หรือ kill -9 pid โดย pid คือโปรเซสที่ต้องการให้หยุดการทำงาน ผู้ใช้งานสามารถสั่งยกเลิกโปรเซสได้เฉพาะโปรเซสที่ตนเองมีสิทธิเท่านั้น เว้นแต่ผู้ที่มีสิทธิ root จึงจะสามารถยกเลิกโปรเซสได้ทุกโปรเซส
เนื่องจากลินุกซ์รองรับการใช้งานจากผู้ใช้หลายคนพร้อมกันและผู้ใช้งานแต่ละคนก็สามารถเรียกใช้งานซอฟต์แวร์ที่แตกต่างกันไปซึ่งก่อให้เกิดโปรเซสได้หลายโปรเซส ระบบปฏิบัติการจะรู้ว่าผู้ใช้งานคนไหนเป็นคนเรียกใช้งานโปรเซสใดจาก RUID (real user id) สำหรับการกำหนดสิทธิของผู้ใช้งานจะดูจาก EUID (effective user id) ซึ่ง EUID อาจจะเหมือนหรือต่างกับ RUID ก็ได้ และเนื่องจากผู้ใช้งานสามารถสังกัดกลุ่ม (group) ได้ ดังนั้นในระดับกลุ่มจะถูกกำหนดโดย RGID (real group id) และ EGID (effective group id) ตามลำดับ
ในแต่ละช่วงเวลาจะมีหลายโปรเซสที่จะใช้งาน CPU แต่แต่ละคอร์ของ CPU สามารถให้บริการได้ทีละโปรเซสในแต่ละช่วงเวลาเท่านั้น เฉพาะโปรเซสที่มีลำดับความสำคัญสูงที่สุดเท่านั้นจึงจะถูกนำไปประมวลผลใน CPU ส่วนโปรเซสที่เหลือจะอยูที่ run queue รอการถูกนำเข้าไปประมวลผลต่อไปตามลำดับความสำคัญ ลำดับความสำคัญของโปรเซสถูกกำหนดที่ nice value หรือ niceness โดยค่าที่น้อยที่สุดจะมีลำดับความสำคัญสูงที่สุด ค่า nice value สามารถเป็นได้ตั้งแต่ -19 ถึง 20 เราสามารถกำหนด real-time priority สำหรับงานที่ต้องการความเร่งด่วนได้ด้วย
ในแต่ละช่วงเวลาจะมีจำนวนโปรเซสที่ใช้งาน CPUแตกต่างกันไป (หมายรวมถึง running stage, waiting stage และ sleeping stage) เราสามารถดูค่าการใช้งาน CPU (CPU Utilization) ได้โดยดูจากค่า load average ด้วยคำสั่ง w หรือ top หรือ uptime
ภาพแสดงการใช้งานคำสั่ง w
จากตัวอย่างจะเห็นค่า load average คือ 0.54, 0.37, 0.19 สมมุติว่าคอมพิวเตอร์ของเรามี 1 CPU ดังนั้นค่าเฉลี่ยของ CPU Utilization แบบที่ใช้เต็มที่ 100% คือ 1.0 ดังนั้นค่าแรก (0.54) หมายถึงเมื่อนาทีที่ผ่านมาค่าเฉลี่ยของ CPU Utilization คือ 54% ค่าที่สอง (0.37) หมายถึง 5 นาทีที่ผ่านมาค่าเฉลี่ยของ CPU Utilization คือ 37% และค่าที่สาม (0.19) หมายถึง 15 นาทีที่ผ่านมาค่าเฉลี่ยของ CPU Utilization คือ 19% ในกรณีที่เรามี CPU หลายคอร์ค่าที่ได้จะต้องหารด้วยจำนวนคอร์ ค่า load average จะบอกเราได้ว่า CPU ทำงานหนักมากแค่ไหน หรือกำลังมีปัญหาว่ามีโปรเซสค้างหรือเปล่า เช่น หากค่าที่สองหรือสาม
สูงมากๆแสดงว่า CPU น่าจะเริ่มไม่พอ และการที่ CPU แสดงค่าที่ 100% หรือมากกว่าหมายถึง CPU overload แล้ว
งานของโปรเซส (job) สามารถทำงานได้ทั้งแบบ background และ foreground ในกรณีของ foreground งานจะถูกทำในเชลล์และในระหว่างที่มันทำงาน งานอื่นๆจะไม่สามารถทำได้ เช่น เวลาเราเรียกคำสั่งในหน้าจอคอทโซลหากคำสั่งนั้นยังทำงานไม่เสร็จ ระบบจะไม่แสดง พรอมท์ให้เราใส่คำสั่งใหม่ ในกรณีของ background งานจะถูกทำนอก เชลล์ดังนั้นจึงไม่จำเป็นต้องรอให้มันทำงานจบก่อนโดยระบบจะแสดง พรอมท์ให้เราใส่คำสั่งอื่นได้เลย งานที่เป็น background จะมีลำดับความสำคัญต่ำเพื่อให้งานที่เป็น foreground ได้รับความสำคัญในการดำเนินการก่อนเพราะต้องตอบสนองต่อผู้ใช้งาน
โดยปรกติงานจะถูกทำในแบบ foreground แต่หากเราต้องการให้ทำงานในแบบ background สามารถทำได้โดยเติม & ต่อท้ายคำสั่ง เช่น updatedb & เราสามารถกด Ctrl+z เพื่อ suspend งานที่เป็น foreground หรือ กด Ctrl+c เพื่อหยุดงานที่เป็น foreground เราสามารถใช้คำสั่ง bg เพื่อให้โปรเซสทำงานในแบบ background หรือ ใช้คำสั่ง fg เพื่อให้โปรเซสทำงานในแบบ foreground เราสามารถแสดงงานที่กำลังทำในแบบ background ได้ด้วยคำสั่ง jobs ซึ่งจะแสดง job ID, สถานะ และ ชื่อคำสั่ง และถ้าใช้คำสั่ง jobs -l จะแสดง PID ด้วย อย่างไรก็ตามงานที่ทำในแบบ background จะสัมพันธ์กับหน้าต่างคอนโซลที่เริ่มทำงาน ดังนั้นคำสั่ง jobs จะไม่แสดงงานที่ถูกเริ่มในหน้าต่างคอนโซลอื่น
ลินุกซ์มีคำสั่งต่างๆเพื่อดำเนินการกับโปรเซสดังนี้
คำสั่ง ps
คำสั่ง ps จะแสดงโปรเซสทั้งหมดพร้อมหมายเลข PID ที่ทำงานอยู่ภายใต้เชลล์ปัจจุบันแต่ถ้าต้องการดูข้อมูลข้อมูลโปรเซสแบบที่มีการปรับปรุงอยู่ตลอดเวลาให้ใช้คำสั่ง top หรือ htop หรีอ atop หรือใช้เครื่องมือในการมอนิเตอร์ในแบบ GUI ของแต่ละดิสทริบิวชั่นแทน คำสั่ง ps มีออปชั่นในการเลือกงานที่ต้องการดู กำหนดข้อมูลและรูปแบบที่ต้องการแสดง เช่น ออปชั่น -u เพื่อแสดงเฉพาะโปรเซสของผู้ใช้งานที่กำหนด หรือใช้ออปชั่น -ef เพื่อแสดงโปรเซสทั้งหมดที่กำลังทำงานอยู่ในระบบพร้อมรายละเอียดที่สำคัญ หรือใช้ออปชั่น -eLf เพื่อแสดงข้อมูลของทุก thread (อย่าลืมว่าโปรเซสสามารถมีได้หลาย thread) นอกจากนี้คำสั่ง ps ยังมีออปชั่นในแบบที่ไม่มีขีดนำหน้าคือ ps aux เพื่อแสดงโปรเซสของผู้ใช้งานทุกคน และ ps axo ที่เราสามารถกำหนดได้ว่าต้องการแสดงข้อมูลอะไรบ้าง
ภาพแสดงตัวอย่างการใช้งานคำสั่ง ps -u
คำสั่ง pstree
คำสั่ง pstree จะแสดงโปรเซสที่กำลังทำงานในรูปแบบไดอะแกรมต้นไม้ ซึ่งจะแสดงให้เห็นความสัมพันธ์ระหว่างโปรเซส เช่น parent โปรเซสของแต่ละโปรเซส เป็นต้น และแสดง thread ในวงเล็บปีกกา
ภาพแสดงตัวอย่างการใช้งานคำสั่ง pstree
คำสั่ง top
คำสั่ง top เป็นคำสั่งที่ใช้ในการแสดงข้อมูลโปรเซสที่กำลังทำงานอยู่ รวมถึงอัตราการใช้ทรัพยากรของเครื่องคอมพิวเตอร์ด้วย ข้อมูลที่แสดงโดยคำสั่ง top จะถูกอัพเดททุกๆ 2 วินาที ดังนั้นเราจึงสามารถใช้คำสั่ง top เพื่อเป็นเครื่องมือในการมอนิเตอร์สุขภาพของระบบได้ การเลิกใช้งาน top ทำโดยกดปุ่ม q
ภาพแสดงตัวอย่างการใช้งานคำสั่ง top
รายละเอียดของข้อมูลที่แสดงโดยคำสั่ง top ประกอบด้วย
บรรทัดแรกจะเป็นข้อมูลว่าระบบเปิดใช้งานมานานแค่ไหนแล้ว ปัจจุบันมีผู้เข้ามาใช้งานที่คน และ load average เป็นอย่างไร
บรรทัดที่สองจะเป็นข้อมูลจำนวนงานที่กำลังทำอยู่ทั้งหมด และแสดงจำนวนในสถานะต่างๆซึ่งสามารถบอกเราได้ถึงสุขภาพของระบบ เช่น เปรียบเทียบจำนวนโปรเซสที่มีสถานะ running กับ load average เพื่อดูว่าระบบเริ่มมีปัญหาเรื่อง capacity หรือยัง หรือใครกำลังใช้งานหนักๆอยู่หรือไม่ หากมีโปรเซสที่มีสถานะ stopped หรือ zombie อาจจะต้องตรวจสอบว่างานที่เกี่ยวข้องกับโปรเซสดังกล่าวว่ามีปัญหาหรือไม่
บรรทัดที่สามเป็นเปอร์เซนต์การใช้งานของ CPU โดยมีค่าต่างๆ คือ us-เป็นเปอร์เซนต์การใช้งานโดยผู้ใช้งาน sy-เป็นเปอร์เซนต์การใช้งานโดยเคอร์เนล ni-เป็นเปอร์เซนต์การใช้ CPU ของงานที่มีลำดับความสำคัญต่ำ id-เป็นเปอร์เซนต์ของ CPU ที่ยังว่างอยู่ (ถ้า id สูง load average ต้องไม่สูง) wa-เป็นเปอร์เซนต์ของงานที่รอ I/O hi-เป็นเปอร์เซนต์การถูกขัดจังหวะ (interrupt) โดยฮาร์ดแวร์ si–เป็นเปอร์เซนต์การถูกขัดจังหวะ (interrupt) โดยซอฟต์แวร์ st-เป็นเปอร์เซนต์ที่ถูกจองใช้งานโดย virtual machine
บรรทัดที่สี่และบรรทัดที่ห้าเป็นข้อมูลการใช้งานหน่วยความจำโดยแบ่งออกเป็นหน่วยความจำจริงๆ (ram) และหน่วยความจำเสมือน ซึ่งหน่วยความจำเสมือนหรือเรีกว่า swap คือการใช้พื้นที่ฮาร์ดิสก์มาช่วยรับโหลดการใช้งาน แต่การอ่านและเขียนลงในฮาร์ดดิสก์จะใช้เวลานานกว่าการอ่านและเขียนลงในหน่วยความจำจริง ถ้าเราพบว่ามีการใช้งาน swap บ่อยๆหรือใช้ swap เยอะขึ้นแสดงว่าได้เวลาต้องเพิ่มหน่วยความจำแล้ว
บรรทัดที่เหลือเป็นข้อมูลของแต่ละโปรเซส โดยเรียงลำดับจากโปรเซสที่ใช้ CPU มากสุดไปยังโปรเซสที่ใช้ CPU น้อยสุด โดยมีข้อมูลต่างๆดังนี้
- Process Identification Number (PID)
- Process owner (USER)
- Priority (PR) and nice values (NI)
- Virtual (VIRT), physical (RES), and shared memory (SHR)
- Status (S)
- Percentage of CPU (%CPU) and memory (%MEM) used
- Execution time (TIME+)
- Command (COMMAND).
ในหน้าจอของ top รองรับการส่งคำสั่งโดยการกดตัวอักษรดังนี้
กด t เพื่อแสดงหรือซ่อนข้อมูลสรุปในบรรทัดที่ 2 และ 3
กด m เพื่อแสดงหรือซ่อนข้อมูลหน่วยความจำในบรรทัดที่ 4 และ 5
กด A เพื่อเรียงลำดับตามอัตราการใช้ทรัพยากร โดยเรียงลำดับจากมากไปน้อย
กด r เพื่อเปลี่ยนค่าลำดับความสำคัญ (nice value ของโปรเซส)
กด k เพื่อยกเลิก (kill) การทำงานของโปรเซส
กด f เพื่อไปยังหน้าการตั้งค่า (configuration) การแสดงผล
กด q เพื่ออกกจากหน้า top
กรณีที่กดคำสั่งผิด เช่น กด r หรือ k ให้กดปุ่ม esc เพื่อยกเลิกคำสั่ง
ลินุกซ์มีคำสั่งและเครื่องมือทีช่วยให้เราสามารถตั้งเวลาให้โปรเซสทำงานตามเวลาที่ต้องการดังนี้
คำสั่ง at
คำสั่ง at เป็นคำสั่งที่ใช้สำหรับการกำหนดเป็นครั้งคราว คำสั่งที่ใช้กับคำสั่ง at จะต้องเป็นคำสั่งที่ไม่ต้องการการโต้ตอบ ตัวอย่างการใช้งานตามภาพด้านล่าง เมื่อเราเรียกคำสั่ง at และกำหนดเวลาแล้ว หน้าจอจะแสดง at> เพื่อรอรับคำสั่งจากเรา จากนั้นปิดด้วยการกด Ctrl+d
ภาพแสดงการใช้งานคำสั่ง at
คำสั่ง cron
คำสั่ง cron เป็นเครื่องมือในการกำหนดให้โปรเซสทำงานตามตารางเวลา (schedule) ที่กำหนด เราตั้งค่า cron โดยการกำหนดในไฟล์ /etc/crontab ซึ่งเป็นตารางการทำงานของ (cron table) โดยระบุคำสั่งและเวลาที่ต้องการโปรเซสทำงาน crontab มีทั้งแบบที่ใช้งานโดยระบบ กับแบบที่ใช้งานโดยผู้ใช้งาน แต่ละบรรทัดใน crontab ประกอบด้วย งาน (job), เงื่อนไขของ crontab, และคำสั่ง เราสามารถแก้ไข crontab โดยเรียกคำสั่ง “ crontab -e” ซึ่งจะเปิดไฟล์ crontab มาให้เราแก้ไข โดยรูปแบบของข้อมูลในแต่ละบรรทัดใน crontab จะมีรูปแบบคือ m h dom mon dow command โดย m หมายถึงนาทีมีค่าได้ตั้งแต่ 0-59, h หมายถึงชั่วโมงมีค่าได้ตั้งแต่ 0-23, dom หมายถึงวันที่มีค่าได้ตั้งแต่ 1-31, mon หมายถึงเดือนมีค่าได้ตั้งแต่ 1-12, dow หมายถึงแต่ละวันในหนึ่งอาทิตย์มีค่าได้ตั้งแต่ 0-6 (0 = วันอาทิตย์) และ cmd คือคำสั่งหรือสคริปที่เราต้องการให้ทำงานตามเวลาที่กำหนด
ตัวอย่างเช่น “ * * * * * /usr/local/bin/execute/this/script.sh ” เป็นการกำหนดให้สคริป script.sh ทำงานทุกนาที ( * อยู่ตรงไหนคือทุกค่าของอันนั้น)
อีกตัวอย่างเช่น “ 30 08 10 06 * /home/sysadmin/full-backup “ เป็นกำหนดให้สคริป full-backup ทำงานในเวลา 8:30 ของทุกวันที่ 10 เดือนมิถุนายน
ภาพแสดงตัวอย่างการกำหนดค่าในไฟล์ contrab
คำสั่ง sleep
คำสั่ง sleep เป็นคำสั่งที่ใช้บอกให้โปรเซสพักการทำงาน โดยโปรเซสจะกลับมาทำงานอีกทีเมื่อถึงเวลาที่กำหนด รูปแบบการใช้คำสั่งคือ sleep NUMBER[SUFFIX]… โดย suffix คือ s-seconds (the default), m-minutes, h-hours และ d-days
ภาพแสดงการใช้งานคำสั่ง sleep ในเชลล์สคริป
การจำกัดขอบเขตของโปรเซส (Process Isolation)
ลินุกซ์เป็นระบบปฏิบัติการที่มีความปลอดภัยสูงเนื่องจากลินุกซ์จะจัดการให้โปรเซสแต่ละตัวไม่มีการเกี่ยวข้องกับโปรเซสอื่น (process isolation) แต่ละโปรเซสไม่สามารถใช้งานทรัพยากรของโปรเซสอื่นได้แม้ว่าจะเป็นโปรเซสที่ถูกเรียกใช้โดยผู้ใช้งานเดียวกันก็ตาม จึงทำให้โปรแกรมไวรัสและโปรแกรมประสงค์ร้ายยากที่จะสุ่มเข้าใช้งานทรัพยากรของระบบ นอกจากนี้ยังมีกลไกอื่นๆเพื่อลดความเสี่ยงทางด้านความปลอดภัย เช่น การทำ Control Groups (cgroups) เป็นการให้ผู้ดูแลระบบสามารถจัดกลุ่มโปรเซสและกำหนดทรัพยากรให้กับกลุ่มโปรเซส การทำ Linux Containers (LXC) ซึ่งเป็นการใช้งานลินุกซ์หลายระบบในรูปแบบคอมเทนเนอร์บนโฮสต์ที่เป็นลินุกซ์ตัวเดียวกันโดยอาศัยความสามารถของ cgroups การทำ Virtualization ซึ่งเป็นการจำลองเครื่องคอมพิวเตอร์หลายๆเครื่องเพื่อทำงานบนเครื่องคอมพิวเตอร์จริงเดียวกัน