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         

ตัวอย่างที่ 1

ตัวอย่างโปรแกรมสำหรับสร้างส่วนของพื้นที่หน่วยความจำสำหรับใช้งานร่วมกัน (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?