InterProcess Communication (IPC): Semaphore

Hari ini, saya belajar IPC dari e-book: Linux Programming Unleashed di part III, ch 16-18. Mungkin bukunya sudah lama, tahun 1999, tapi informasinya masih cukup relevan, perbedaannya hanya ada di implementasinya saja (sebagian besar contoh kode, tidak bisa diimplementasikan, maklum, perkembangan Linux sangat dinamis). Salah satu yang ingin saya implementasikan adalah Semaphore, salah satu metode IPC. Semaphore ini akan digunakan untuk mengkoordinasikan processes yang mengakses satu resource, sehingga beberapa proses tidak akan mengakses resource secara bersamaan.

Seputar IPC

IPC digunakan untuk membangun aplikasi terdistribusi. Linux menyediakan beberapa metode IPC, yaitu:

  • pipes: menyediakan one-way communication channel. Jenisnya: 1) unnamed-pipe untuk komunikasi antara parent process dan child (atau forked) process dan 2) named-pipe untuk komunikasi antar program berbeda yang mengakses file system yang sama secara bersama-sama. Metode ini digunakan oleh program di satu komputer
  • message queue: digunakan saat ingin mengirim beberapa tipe data message dan penerima ingin memfilter message tersebut berdasarkan tipenya. Banyak digunakan di program-program Unix lama. Digunakan dalam satu komputer
  • shared memory: digunakan untuk mendapatkan very high performance IPC antar proses dalam satu komputer. Ini memerlukan konfigurasi bootloader untuk memesan shared memory yang akan digunakan. Misalnya punya memori fisik 512MB, maka di grub/lilo parameter kernel untuk “mem=” perlu ditambahkan, yaitu mem=500m, untuk memesan 12MB memori untuk shared. Ini diperlukan agar memori tersebut khusus untuk proses/program tertentu, tidak akan dioverwritten oleh program lain.
  • semaphore: digunakan untuk sharing resource yang hanya dapat diakses oleh satu proses dalam satu waktu. Akan dijelaskan lebih lengkap di bawah
  • TCP/UDP socket: digunakan untuk komunikasi antar process/program/komputer. Di artikel mendatang, akan dibahas lebih lanjut lagi.
  • multicast/broadcast IP: digunakan untuk membangun sistem terdistribusi, seperti chat, community blackboard drawing, dan video conference lewat UDP dengan alamat IP multicast. Kernel harus dikonfigurasi untuk mendukung Multicast IP.
  • non-blocking socket I/O

Penjelasan lengkap dapat dilihat dalam buku tersebut. Dalam artikel ini, hanya tentang semaphore. mungkin lain kali, akan diulas lebih lanjut metode yang lain.

Semaphore

Sistem call yang digunakan adalah:

  • semget – menghasilkan index semaphore (integer) yang diberikan oleh kernel
  • semop – melakukan operasi ke semaphore
  • semctl – melakukan operasi kontrol ke semaphore

Listing program untuk mengaplikasikan semaphore adalah sebagai berikut:

#include <sys/sem.h>
#include <string.h>
static struct sembuf op_lock[2] = {
	{0, 0, 0},		// wait for sem#0 to become 0
	{0, 1, SEM_UNDO}	// then incremnet sem# by 1
};
static struct sembuf op_unlock[1] = {
	{0, -1, (IPC_NOWAIT|SEM_UNDO)}	// decremet sem#0 by 1
};
int create_sema()
{
	int sem_id;
	int retval;
	union semun {
		int val;                       /*value for SETVAL*/
		struct semid_ds *buf;  /*buffer for IPC_STAT & IPC_SET*/
		ushort *array;             /*array for GETALL & SETALL*/
	} semctl_arg;
	/*buat 1 semaphore*/
	sem_id = semget( IPC_PRIVATE, 1, 0666|IPC_CREAT);
	if( sem_id<0)
	{
		printf("get sema: failed : %s", strerror(errno));
		return -1;
	}
	semctl_arg.val = 1; /*specify the value*/
	retval = semctl( sem_id, 0, SETVAL, semctl_arg); /*make sure that everything is set up OK*/
	if( retval== -1)
	{
		printf("set sema: failed: %s", strerror(errno));
		remove_sema( sem_id);
		return -1;
	}
	return sem_id;
}
void sem_wait( int sem_id)
{
	semop( sem_id, &op_lock[0], 2);	/*increment semaphore*/
}
void sem_signal( int sem_id)
{
	semop( sem_id, &op_unlock[0], 1); /*decrement semaphore*/
}
/*remove the semaphore*/
int remove_sema( int sem_id)
{
	int retval = semctl( sem_id, 0, IPC_RMID);
	if( retval== -1)
	{
		printf("remove sema: failed: %s", strerror(errno));
	}
	return 1;
}

Keterangan:

  • Create semaphore dengan create_sema()
  • Jika akan mengakses resource, set semaphore dengan sem_wait(sem_id)
  • Jika telah selesai mengakses, bebaskan resource, dengan sem_signal(sem_id)
  • Release semaphore dengan remove_sema(sem_id)

Kita bisa menggunakan rutin-rutin tersebut di atas untuk mengimplementasikan semaphore di program kita.

Tag: ,

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: