Skip navigation


Salah satu hal yang menarik saat kemarin kuliah IF4038 Pemrograman Sistem adalah tentang zombie process. Zombie process adalah sebuah proses pada sistem operasi yang telah menyelesaikan eksekusinya tetapi terdapat pada entry process.

Di dalam sistem operasi UNIX terdapat sebuah konsep parent process dan child process. Dengan menggunakan system call fork. Sebuah process dapat menciptakan sebuah process lain yang menduplikasikan seluruh image dari process tersebut.

/* fork1.c */
#include <stdio.h>
int main(int argc, char * argv[])
{
	fork();
	puts("Hello World!");
}


System call fork() memberikan nilai kembalian process id child pada parent dan nilai 0 pada child process. Jika forking gagal dilakukan maka nilai kembaliannya adalah bilangan negatif. Dengan cara ini child process dan parent process dapat diatur sehingga dapat melakukan aksi yang berbeda. Sebagai contoh.

/* fork2.c */
#include <stdio .h>
#include <sys /types.h>

int main(int argc, char * argv[])
{
	pid_t childpid = fork();
	if (childpid == 0) /* Child proces */
		printf("I am the child. My PID is %d. My Parent ID is %d\n", getpid(), getppid());
	else if (childpid > 0) /* Parent process */
		printf("I am the parent. My PID is %d. My Child ID is %d\n", getpid(), childpid);
	else /* Failed */
		puts("Failed to fork");
}

Hasilnya bisa dilihat,

petra@petra-desktop:~/IF4038$ ./fork2
I am the child. My PID is 5463. My Parent ID is 5462
I am the parent. My PID is 5462. My Child ID is 5463

Mari kita coba-coba lihat pada process table untuk kode di bawah ini

/* fork3.c */
#include <stdio.h>
#include <sys/types.h>

int main(int argc, char * argv[])
{
	pid_t childpid = fork();
	if (childpid == 0) /* Child proces */
		for( ; ; ) printf("C [%d]\n", getpid());
	else if (childpid > 0) /* Parent process */
		for( ; ; ) printf("P [%d]\n", getpid());
	else /* Failed */
		puts("Failed to fork");
}

Process tablenya jika kode dieksekusi

petra@petra-desktop:~/IF4038$ ps axj
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 5420  6006  6006  5420 pts/1     6006 R+    1000   0:00 ./fork3
 6006  6007  6006  5420 pts/1     6006 R+    1000   0:00 ./fork3
 5470  6010  6010  5470 pts/2     6010 R+    1000   0:00 ps axj

Zombie process akan terjadi kalau PID 6007 kita beri signal kill

petra@petra-desktop:~/IF4038$ kill -9 6007
petra@petra-desktop:~/IF4038$ ps axj
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 5420  6006  6006  5420 pts/1     6006 R+    1000   0:53 ./fork3
 6006  6007  6006  5420 pts/1     6006 Z+    1000   0:49 [fork3] <defunct>
 5470  6053  6053  5470 pts/2     6053 R+    1000   0:00 ps aj

Bisa dilihat 6007 tetap berada pada process table hanya saja ditandai dengan <defunct> Process ini lah yang disebut dengan zombie process. Sebenarnya process ini sudah berhenti dieksekusikan oleh CPU. Ketika process ini berhenti dieksekusi process ini akan mengirimkan signal SIGCHLD ke parent process. Ketika parent process tidak menghandle signal tersebut maka child process akan seakan-akan tetap hidup.
Lain halnya kalau tadi kita memberi signal kepada parent process

petra@petra-desktop:~/IF4038$ ./fork3
petra@petra-desktop:~/IF4038$ ps axj
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 5420  6104  6104  5420 pts/1     6104 R+    1000   0:01 ./fork3
 6104  6105  6104  5420 pts/1     6104 R+    1000   0:01 ./fork3
 5470  6107  6107  5470 pts/2     6107 R+    1000   0:00 ps aj
petra@petra-desktop:~/IF4038$ kill -9 6104
petra@petra-desktop:~/IF4038$ ps axj
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    1  6105  6104  5420 pts/1     5420 R     1000   0:12 ./fork3
 5470  6115  6115  5470 pts/2     6115 R+    1000   0:00 ps aj

Child process akan diadopsi oleh process dengan PID 1 yakni init. Sepertinya parent process tidak perlu memberitahu child process saat berhenti eksekusi.
Untuk mencegah hal ini dibutuhkan satu syscall lagi, yakni wait() atau waitpid()

/* fork4.c */
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char * argv[])
{
	int stat;
	pid_t childpid = fork();
	if (childpid == 0) /* Child proces */
		for( ; ; ) printf("C [%d]\n", getpid());
	else if (childpid > 0) /* Parent process */
	{
		printf("Waiting....\n");
		wait(&stat);
		printf("Child end result %d\n", stat);
	}
	else /* Failed */
		puts("Failed to fork");
}

Moral dari cerita ini adalah,

Anak itu kalau mau mati pergi harusnya salaman baik-baik sama bapaknya

~ Pak Riza Satria Perdana S.T. M.T.

Akan tetapi agak sedikit rancu, bagaimana kalau si Bapaknya yang ngusir? Sebagai contoh

/* fork5.c */
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char * argv[])
{
	int stat;
	pid_t childpid = fork();
	if (childpid == 0) /* Child proces */
		for( ; ; ) printf("C [%d]\n", getpid());
	else if (childpid > 0) /* Parent process */
	{
		int i;
		for (i = 0; i < 5; i++)
		{
			sleep(1);
		}
		kill(childpid, SIGKILL);
		for ( ; ; );
	}
	else /* Failed */
		puts("Failed to fork");
}&#91;/sourcecode&#93;

Pada kode di atas, setelah 5 detik, parent process akan mengirimkan signal SIGKILL kepada <em>child process</em> kemudian masuk ke <em>infinite loop</em>.
sebelum detik ke 5
<pre>petra@petra-desktop:~/IF4038$ ps aj
PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
5420  6611  6611  5420 pts/1     6611 S+    1000   0:00 ./fork5
6611  6612  6611  5420 pts/1     6611 R+    1000   0:00 ./fork5</pre>
setelah detik ke 5
<pre>petra@petra-desktop:~/IF4038$ ps aj
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 5420  6611  6611  5420 pts/1     6611 R+    1000   0:00 ./fork5
 6611  6612  6611  5420 pts/1     6611 Z+    1000   0:02 [fork5]</pre>
Salah satu solusinya ya jelas dengan menambahkan <em>syscall wait()</em> setelah<em> kill()</em>
Jelas kebijaksanaan Pak Riza di atas dapat ditambahkan
<blockquote>
<div style="font-size:16px;font-style:italic;font-weight:bold;letter-spacing:1px;">Anak itu harus tau diri, sebelum <del datetime="00">mati dibunuh</del> pergi diusir bapaknya harus salaman baik-baik</div>
~ Petra Novandi Barus (calon) S.T.</blockquote>
Ada satu hal lagi yang masih belum diklarifikasikan. Bagaimana kalau <em>child process</em> yang memberi signal SIGKILL kepada <em>parent process</em>?

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char * argv[])
{
	int stat;
	pid_t childpid = fork();
	if (childpid == 0) /* Child proces */
	{
		pid_t parentpid = getppid();
		int i;
		for (i = 0; i < 5; i++)
		{
			sleep(1);
		}
		kill(parentpid, SIGKILL);
		for( ; ; ) ;
	}
	else if (childpid > 0) /* Parent process */
		for( ; ; ) printf("P [%d]\n", getpid());
	else /* Failed */
		puts("Failed to fork");
}

Kode di atas hanya dibalik dari kode sebelumnya. Child process akan mengirimkan signal SIGKILL kepada parent process setelah 5 detik.
Hasilnya setelah 5 detik adalah

petra@petra-desktop:~/IF4038$ ps aj
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    1  6884  6883  5420 pts/1     5420 R     1000   0:00 ./fork6

Kurang ajar banget! Abis ngusir bapaknya, dia langsung cari orang tua baru….. (sebenarnya sudah bisa diduga sih)
Well, ternyata *NIX mengajarkan moral yang tidak bagus. *sigh*

Ya sudah lah. Gak usah ditiru.

3 Comments

  1. Pesan2 moral yang bagus, hapalin moralnya aja, biar gampang..

    Males baca semua sih.. Hahaha..

  2. analoginya mantap🙂

  3. saya sangat suka banget :*


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: