Showing posts with label system call. Show all posts
Showing posts with label system call. Show all posts

Thursday, August 30, 2012

UNIX Programing

The Life Cycle of A Process (ต่อ)


เรามาว่ากันเรื่องนี้ต่อจากตอนที่ค้างอยู่ ในตอนใหม่นี้เลย น่ะครับ
ขอท้าวความเดิมที่ทิ้งไว้ตรงย่อหน้าสุดท้าย ความว่า

fork จะมีคุณสมบัติโดดเด่นจำเพาะตัวอยู่อย่างหนึ่งคือ เขาจะคืนค่ากลับมา ๒ ค่า  โดยจากมุมของ ทารก ที่เกิดมาแล้ว fork จะคืนค่า ศูนย์ (0) มาให้เสมอ   แต่กับพ่อแม่ หรือ ผู้ให้กำเนิด ในอีกมิติหนึ่งจะได้รับหมายเลข PID ของทารกที่เพิ่งเกิดมา  ถ้าจะเปรียบเทียบกับคน ก็หมายเอาว่า ได้หมายเลขประชาชนของลูก นั่นแหละ

และนี่คือส่วนที่ทั้ง ๒ โปรเซส สามารถแยกระหว่างกันและกันออกได้ ในภาษา C ที่พอยกมาให้เห็นกันตอนนี้ง่ายๆ

/*
 * fork()
 */

#include <sys/types.h>
#include <unistd.h> 

int main(int argc, char *argv[])
{

pid_t proc_id;

proc_id = fork();

if (proc_id == 0) {
    /* อันนี้เป็นส่วนของ child โปรเซส ก็จะมีพฤติกรรมแบบทารกทั่วๆไป */
} else {
    /* ตรงนี้ เป็นส่วนของ parent */
}
}


Control of Processes

จักขอกล่าว พอได้สาระในส่วนของ child ก่อนแต่พอสังเขปดังนี้

ภายหลัง fork() โปรเซสใหม่มักจะเรียกใช้บริการของ system calls ในตระกูล exec ดังได้กล่าวมาแล้วนั้นเสมอ ซึ่งเมื่อดำเนินการเสร็จสิ้นแล้วก็ ตายไปตามกาล ส่วนของ parent นั้นหากไม่มีอะไรมาก ก็มักจะยกภาระแลทรัพย์สินทั้งมวล (หน่วยความจำ) ให้กับ ลูก ที่เกิดขึ้นแล้วตัวเองก็ ตายเมื่องานสร้างทารกจบสิ้นลงด้วยดี


เป็นเช่นนี้แล้ว ใครจะเป็นผู้ดูแล โปรเซส ของทารกที่เกิดใหม่นี้

การที่จะตอบคำถามนี้ ขอท้าวความไปในตอนแรก อีกสักหนนึง ช่วงที่คอมพิวเตอร์เปิดเครื่องมาแล้ว kernel ทำงานนั้น kernel เขาสร้าง โปรเซศ มามากมายโดยอัตโนมัติ และที่โดดเด่นที่สุดในนั้นคือ init (ไม่รู้ออกเสียงยังไง จะเรียกว่า อีนิด กะดูว่าฝรั่งจะรู้จักคำว่า ไอ้ อี ด้วยรึ งงงๆยุ)  ทุกโปรเซสที่ไม่ใช่สร้างโดย kernel จะเป็นเทือกเถาเหล่ากอของ init ทั้งนั้น

ดังนี้แล้วเมื่อโปรเซสใดโปรเซสหนึ่ง พร้อมที่จะตาย คือจบงานแล้วนั่นแหละ   โปรเซสนั้นจะเรียกรูทีน _exit เพื่อแจ้ง kernel ว่าพร้อมแล้ว และก็มี  exit code เป็นของฝาก  มาให้ พ่อ-แม่ที่สร้างโปรเซสนั้นๆ เอาไปดูผลงานด้วย (exit code = 0 ถือว่า ทำงานสำเร็จ)

ข้างฝ่าย kernel เมื่อได้รับแจ้ง
  1. ก็จะจับเก็บ exit code นี้เอาไว้ จนกว่าจะมีรายการทวงของฝาก จากพ่อ-แม่ ผ่านทาง system call ที่ชื่อ wait  
  2. หน่วยความจำที่โปรเซสที่แจ้งตายนั้นใช้อยู่ ก็จะถูกเรียกกลับคืนมาสู่ส่วนกลาง

โปรเซส นั้นจะไม่ได้รับเจียดเวลา แม้ สักส่วนเสี้ยว ของ หน่วยเวลา จาก cpu อีกต่อไป  แต่ก็ยัง คงสถานะเอาไว้ จนกว่าพ่อ-แม่ จะมาจับไป ให้รางวัล หรือ ลงโทษลงทัณฑ์ อย่าใดอย่าหนึ่งนั่นแหละ   ถึงจะถูกลบสถานะออกจากระบบโปรเซส

โปรเซส ที่อยู่ระหว่างการแจ้งตายนี้ เรียกว่า zombie
พอมาถึงตรงนี้ กะคงพอมองเห็นเค้าลางของ อนาคตของโปรเซส ที่ถามานั้นได้

ที่เล่ามาก็ดูว่า OK น่ะ ในกรณีที่พ่อ-แม่ผู้สร้าง โปรเซส นั้นไม่ตายก่อนและยังเรียกหาโปรเซสลูก ด้วย wait() ในแบบนี้จะไม่มี zombie เกิดขึ้น  ตัวอย่างของ C codes ข้างล่างนี้แสดง process control ในแนวนี้

/*
 * parents wait  

 */

#include <sys/types.h>

#include <sys/wait.h>
#include <unistd.h> 

int main(int argc, char *argv[])
{    
    pid_t proc_id; 
    int status;

   proc_id = fork();

   if (proc_id == 0) {
        /* อันนี้เป็นส่วนของ child โปรเซส ก็จะมีพฤติกรรมแบบทารกทั่วๆไป */
        execl("/bin/sh", "sh",  NULL);
    } else {
        wait(&status); 
            /* สาระของงานที่ต้องทำต่อ เช่น ตรวจดูว่า จบงานลักษณะไหน 
             * stopped, terminated, continue, หรือโดยวิธีอื่น
             */
    }
}

wait() จะดูว่า ทารกจบงานอย่างไร ถ้าจบงานด้วย stopped, continued, terminated เหล่านี้ wait() จะได้ส่งค่า process id ของ ทารกนั้นให้กับ main() เพื่อเคลียร์งานต่อไป

ถ้าพ่อ-แม่ผู้สร้าง โปรเซส ขึ้นมานั้นชิงตายหนีไปก่อน ในกรณีนี้ kernel ก็ไม่รู้จะเก็บ exit code นั้นเอาไว้ทำไม เพราะไม่มีคิวคำขอ exit code นั้นจาก wait()    ดังนี้แล้ว kernel จึงได้แต่บริจาค zombie นั้นให้กับ init ไปอย่างเดียว เท่านั้น

ตัวอย่าง C codes ในส่วนนี้ ก็คล้ายกับส่วนแรก เพียงไม่ต้อง wait(&status); เท่านั้นเอง ดังนี้

/*
 * parents die first

 */
 
#include <sys/types.h>
#include <unistd.h> 

int main(int argc, char *argv[])
{

     pid_t proc_id; 

    proc_id = fork();

    if (proc_id == 0) {
        /* อันนี้เป็นส่วนของ child โปรเซส ก็จะมีพฤติกรรมแบบทารกทั่วๆไป */
        execl("/bin/sh", "sh",  NULL);
     }


กะคงพอให้สาระในเรื่องของ process control กันบ้างน่ะครับ

อย่างไรก็ดี คราวนี้ต้องยอมรับสภาพร่างกายจริงๆครับ เลยทำให้ชะงักไปร่วมเดือน  และแม้แต่ครั้งนี้ ก็เร่งรีบอยู่น่ะ  มะฃาม ต้องขอตรวจรายละเอียดของเรื่อง main function ให้ชัดๆอีกหนก่อนละกัน

ขอขอบคุณมากครับ ที่สละเวลามาอ่านข้อเขียนในชุดนี้

Monday, August 6, 2012

UNIX Programming

ใน ตอนที่ผ่านมา พูดถึง process creation ด้วย execl แล้วก็มาต่อด้วยบทแทรกคั่นรายการด้วย สวรรค์ และทิ้งท้ายด้วยข้อสงสัยว่า ที่ว่า process creation นั้น มันตรงไหนกันแน่

มาตอนนี้เรามาต่อกันด้วยเรื่องราวของ วัฏจักร หรือวงจรชีวิตของ process กันสักเล็กน้อย เพื่อเสริมความรู้เรื่องโปรเซสกันก่อน แล้ว หลังจากนั้นเราจึงค่อยมาว่ากันต่อไป ส่วนจะจบตอนเลยทีเดียว หรือไม่ นั้น กะค่อยๆมาพิจารณากันอีกที เน้าะ

เอกสารอ้างอิงสำหรับตอนนี้กะมีอยู่ ๒ เล่ม แต่จะยกมาเพียงเล่มแรก ส่วนเล่มที่ ๒ นั้นมีภาพประกอบที่เห็นว่า ทั่วไป เลยไม่เอามา แต่กะสมควรที่จะหามาอ่าน สำหรับท่านที่สนใจ
  1. Evi Nemeth, Garth Snyder, Scott Seebass, Trent R. Hein; UNX SYSTEM ADMINISTRATOE HANDBOOK; Prentice Hall — the Red Book
  2. AEleen Frisch; Essentail System Administration; O'Reilly — the White Book

The Life Cycle of A Process

โปรเซส นั้น ไม่ใช่ว่า อยู่ดีดีก็จะโผล่มาในระบบอย่างมหัศจรรย์ หรือ kernel สร้างขึ้นมาเองอย่างไม่หยุดหย่อน  โปรเซสใหม่นั้น ถูกสร้างขึ้นมาจากโปรเซสอื่น ก็คล้ายๆกับคนใหม่นั่นแหละ — มีข้อที่ควรระวังอยู่คือ คนใหม่นั้นเกิดมาจากคนอื่น ไม่ใช่จาด UNIX โปรเซสแต่อย่างใด อย่าได้เข้าใจคลาดเคลื่อนไป 

ในการสร้างโปรเซสใหม่ โปรเซสเดิม จะผลิต สำเนา ของตัวตนของตนเองขึ้นมา ด้วยวิธีการที่เรียกกันว่า system call ผ่านระบบปฏิบัติการ อีกทีหนึ่ง คำสั่งที่ว่านี้คือ fork

สำเนา ที่สร้างขึ้นมาจากต้นฉบับเดิมนั้น เหมือน ต้นฉบับเดิม แทบทุกประการ ยกเว้นสิ่งเหล่านี้ คือ

  1. โปรเซสใหม่มีหมายเลข PID ของตัวเองจำเพาะไปเลย
  2. หมายเลข PPID ของโปรเซสใหม่จะอ้างถึง หรือ ชี้ไปยังโปรเซสต้นฉบับ
  3. ข้อมูลบัญชีของโปรเซสใหม่จะถูก reset
  4. โปรเซสใหม่ จะมี file descriptor เป็นของของตัวเอง
fork จะมีคุณสมบัติโดดเด่นจำเพาะตัวอยู่อย่างหนึ่งคือ เขาจะคืนค่ากลับมา ๒ ค่า  โดยจากมุมของ ทารก ที่เกิดมาแล้ว fork จะคืนค่า ศูนย์ (0) มาให้เสมอ   แต่กับพ่อแม่ หรือ ผู้ให้กำเนิด ในอีกมิติหนึ่งจะได้รับหมายเลข PID ของทารกที่เพิ่งเกิดมา  ถ้าจะเปรียบเทียบกับคน ก็หมายเอาว่า ได้หมายเลขประชาชนของลูก นั่นแหละ

View My Stats