System V
Shared Memory based on System V
หน่วยความจำที่ถูกใช้ร่วมกัน หรือเรียกว่า shared memory นั้นเป็นพื้นที่ที่จะให้โปรเซสทั้งหลายสามารถใช้เป็นที่แลกเปลี่ยนสื่อสารข้อมูลระหว่างกันได้ ซึ่ง shared memory นี้เป็นพื้นที่ของหน่วยความจำเสมือน (virtual address space) โดยแต่ละหน้า (page) ของหน่วยความจำเสมือนนี้จะถูกอ้างอิงโดยชุดเก็บตารางของแต่ละหน้า (page table) ในแต่ละตารางหน้าของโปรเซสที่กำลังใช้งานร่วมกัน ในระบบ System V การเข้าถึงพื้นที่ของหน่วยความจำที่ใช้งานร่วมกันนั้นจะถูกควบคุมไปกับชุดกุญแจและการตรวจสอบสิทธิ์การเข้าถึง (access rights)
เมื่อเกิดพื้นที่หน่วยความจำส่วนหนึ่งกลายเป็น shared memory segments ขึ้น ก็ยังไม่มีกลไกการตรวจสอบว่าจะให้แต่ละโปรเซสเข้าใช้งานอย่างไร ซึ่งจะต้องใช้กลไกอย่างอื่นช่วยเหลือแทน ตัวอย่างเช่น System V semaphores ที่ทำให้มีการทำงานที่สอดคล้องกัน เพื่อให้การเข้าถึงหน่วยความจำนี้ไม่เกิดปัญหา เป็นต้น
ฟังก์ชันและตัวแปรที่เกี่ยวข้อง
ไลบรารีที่เกี่ยวข้องคือ
sys/ipc.h
,sys/types.h
และsys/shm.h
ฟังก์ชัน
int shmget(key_t key, size_t size, int shmflg);
ในการสร้างกุญแจ (key) นั้นจะมีขบวนการคล้ายกับการสร้างกุญแจของ message queues ด้วยฟังก์ชัน
ftok()
ถัดมาจะเป็นขนาด (size
) ของส่วนของหน่วยความจำที่เข้าใช้งานร่วมกัน (shared memory segment) ในส่วนสุดท้าย (shmflg
) จะเป็นการกำหนดสิทธิการเข้าถึงและแฟลกที่ระบุการสร้าง (IPC_CREAT
) ซึ่งเมื่อสามารถสร้างส่วนพื้นที่หน่วยความจำนี้ได้ฟังก์ชันshmget()
จะส่งค่าหมายเลขของพื้นที่ (shmid
) ออกมา
ดังตัวอย่างการกำหนดสิทธิให้เป็น 644 (rw-r--r--)
ในส่วนพื้นที่ขนาด 1KB
ฟังก์ชัน
void *shmat(int shmid, void *shmaddr, int shmflg);
ใช้เพื่ออ่านค่าพอยเตอร์ที่ชี้ไปยังส่วนพื้นที่สำหรับเก็บข้อมูล ซึ่งอ้างอิงจากหมายเลขพื้นที่หน่วยความจำ (
shmid
) ที่ได้รับจากฟังก์ชันshmget()
สำหรับส่วนของพื้นที่หน่วยจำที่จะให้ใช้นั้นก็ระบุในตัวแปรshmaddr
แต่อย่างไรก็ตามควรจะกำหนดให้เป็นศูนย์ (0
) เพื่อปล่อยให้ระบบปฏิบัติการเป็นคนเลือกให้ตามความเหมาะสมเอง สำหรับแฟลก (shmflg
) นั้นสามารถที่จะถูกกำหนดให้เป็นSHM_RDONLY
ได้ถ้าต้องการเพียงแค่อ่าน หรืออีกอย่างหนึ่งก็ตั้งให้เป็นศูนย์ (0
) เพื่อใช้ทั้งอ่านและเขียน
ดังตัวอย่างการดึงตำแหน่งของพื้นที่สำหรับเก็บข้อมูลขนาด 1KB
ข้างล่างนี้
ดังนั้นเมื่อได้ตำแหน่งชี้พื้นที่เก็บข้อมูล ((char)*data) เรียบร้อยแล้ว ต่อไปก็เป็นเพียงการเรียกฟังก์ชันพื้นฐานสำหรับอ่านและเขียนค่าที่เป็นชนิดข้อความลงไปในพื้นที่ดังกล่าว ตัวอย่างเช่น เมื่อต้องการแสดงค่าที่อยู่ในส่วนของพื้นที่หน่วยความจำนั้น
หรือต้องการบันทึกข้อมูลลงไปในพื้นที่ส่วนนั้น
ฟังก์ชัน
int shmdt(void *shmaddr);
ใช้เมื่อต้องการถอนออกจากการเข้าใช้พื้นที่หน่วยความจำโดยการระบุตำแหน่งของพื้นที่ของหน่วยความจำนั้น (
shmaddr
) ที่ได้มาจากฟังก์ชันshmat()
สามารถใช้คำสั่ง ipcs เพื่อต้องการแสดงรายการของส่วนพื้นที่หน่วยความจำที่เปิดใช้งานร่วมกัน และสามารถใช้คำสั่ง ipcrm เพื่อลบหน่วยความจำนั้นทิ้งได้เช่นกัน
ตัวอย่างโปรแกรมสำหรับสร้างส่วนของพื้นที่หน่วยความจำสำหรับใช้งานร่วมกัน (shared memory segments) และการเข้าใช้งานพื้นฐาน
ทำการคอมไพล์และรันโปรแกรม โดยใส่อาร์กิวเม้นต์เป็นชุด
สิ่งที่ควรรู้
เนื่องจากพื้นที่หน่วยความจำส่วนนี้เป็นส่วนที่แชร์ให้แต่ละโปรเซสสามารถเข้าถึงได้ ดังนั้นอาจจะเกิดเหตุการณ์ที่มีมากกว่าหนึ่งโปรเซสต้องการเข้ามาเพื่อทำการเขียนข้อมูลลงในพื้นที่ส่วนนี้พร้อมในเวลาเดียวกัน (concurrency) ผลกระทบจากการเข้าใช้พื้นที่ในเวลาเดียวกันนี้ อาจจะทำให้เกิดการเสียหายของข้อมูลที่แต่ละโปรเซสได้เขียนลงไป แล้วส่งผลให้โปรเซสที่ต้องการจะอ่านข้อมูลจากพื้นที่นี้เพื่อนำไปประมวลผลต่อเกิดความเสียหายได้ ดังนั้นเพื่อแก้ปัญหาการเข้าใช้งานทรัพยากรที่แชร์ร่วมกันภายในระบบ จึงจำเป็นจะต้องมีกลไกการควบคุมและจัดการเหตุการณ์ที่โปรเซสจะเข้ามาพร้อมกันในเวลาเดียวกัน เช่นเทคนิค Semaphore เป็นต้น ซึ่งจะกล่าวถึงในบทถัดไป
Last updated