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 ที่ทำให้มีการทำงานที่สอดคล้องกัน เพื่อให้การเข้าถึงหน่วยความจำนี้ไม่เกิดปัญหา เป็นต้น
สามารถใช้คำสั่ง ipcs เพื่อต้องการแสดงรายการของส่วนพื้นที่หน่วยความจำที่เปิดใช้งานร่วมกัน และสามารถใช้คำสั่ง ipcrm เพื่อลบหน่วยความจำนั้นทิ้งได้เช่นกัน
$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 294912 sriborriru 600 524288 2 dest
0x00000000 1245185 sriborriru 600 524288 2 dest
0x00000000 425986 sriborriru 600 524288 2 dest
0x00000000 622595 sriborriru 600 524288 2 dest
0x00000000 786436 sriborriru 600 524288 2 dest
0x00000000 819205 sriborriru 600 33554432 2 dest
ตัวอย่างโปรแกรมสำหรับสร้างส่วนของพื้นที่หน่วยความจำสำหรับใช้งานร่วมกัน (shared memory segments) และการเข้าใช้งานพื้นฐาน
// shmdemo.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_SIZE 1024 /* make it a 1K shared memory segment */
int main(int argc, char *argv[]) {
key_t key;
int shmid;
char *data;
if (argc < 2) {
fprintf(stderr, "usage: ./shmdemo [data_to_write]\n");
exit(1);
}
/* make the key: */
if ((key = ftok("shmdemo.c", 'R')) == -1) {
perror("ftok");
exit(1);
}
/* connect to (and possibly create) the segment: */
if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
perror("shmget");
exit(1);
}
/* attach to the segment to get a pointer to it: */
data = shmat(shmid, (void*) 0, 0);
if (data == (char*) (-1)) {
perror("shmat");
exit(1);
}
/* read or modify the segment, based on the command line: */
if (argc == 2) {
printf("writing to segment: \"%s\"\n", argv[1]);
strncpy(data, argv[1], SHM_SIZE);
} else
printf("segment contains: \"%s\"\n", data);
/* detach from the segment: */
if (shmdt(data) == -1) {
perror("shmdt");
exit(1);
}
return 0;
}
ทำการคอมไพล์และรันโปรแกรม โดยใส่อาร์กิวเม้นต์เป็นชุด
$ gcc -o shmdemo shmdemo.c
$ ./shmdemo ─╯
usage: shmdemo [data_to_write]
$ ./shmdemo "I'm going to access this shared memory segment..."
writing to segment: "I'm going to access this shared memory segment..."
สิ่งที่ควรรู้
เนื่องจากพื้นที่หน่วยความจำส่วนนี้เป็นส่วนที่แชร์ให้แต่ละโปรเซสสามารถเข้าถึงได้ ดังนั้นอาจจะเกิดเหตุการณ์ที่มีมากกว่าหนึ่งโปรเซสต้องการเข้ามาเพื่อทำการเขียนข้อมูลลงในพื้นที่ส่วนนี้พร้อมในเวลาเดียวกัน (concurrency) ผลกระทบจากการเข้าใช้พื้นที่ในเวลาเดียวกันนี้ อาจจะทำให้เกิดการเสียหายของข้อมูลที่แต่ละโปรเซสได้เขียนลงไป แล้วส่งผลให้โปรเซสที่ต้องการจะอ่านข้อมูลจากพื้นที่นี้เพื่อนำไปประมวลผลต่อเกิดความเสียหายได้ ดังนั้นเพื่อแก้ปัญหาการเข้าใช้งานทรัพยากรที่แชร์ร่วมกันภายในระบบ จึงจำเป็นจะต้องมีกลไกการควบคุมและจัดการเหตุการณ์ที่โปรเซสจะเข้ามาพร้อมกันในเวลาเดียวกัน เช่นเทคนิค Semaphore เป็นต้น ซึ่งจะกล่าวถึงในบทถัดไป
Last updated
Was this helpful?