PRAKTIKUM 8 UNIX SYSTEM CALL dan MANAJEMEN MEMORY
LAPORAN
SEMENTARA PRAKTIKUM 7
UNIX
SYSTEM CALL dan MANAJEMEN MEMORY
Di
susun Oleh :
PUTRI
AYUNA QOLBY SYIFA’A
2003421015
BM-5B
PROGRAM
STUDI BROADBAND MULTIMEDIA
JURUSAN
TEKNIK ELEKTRO
POLITEKNIK
NEGERI JAKARTA
2022
I.
PERCOBAAN 1 : Melihat Proses Parent
dan proses child
1.
Dengan menggunakan editor vi, buatlah file
fork1.cpp dan ketikkan program berikut:
#include <iostream>
using namespace std;
#include <sys/types.h> #include
<unistd.h>
/* getpid() adalah system call yg dideklarasikan
pada unistd.h.
Menghasilkan suatu nilai dengan type pid_t.
pid_t adalah type khusus untuk process id yg
ekuivalen dg int
*/
int main(void) {
pid_t mypid;
uid_t myuid;
for (int i = 0; i < 3; i++) {
mypid = getpid();
cout << "I am process " <<
mypid << endl;
cout << "My parent is process "
<< getppid() << endl; cout << "The owner of this process has uid " << getuid()
<< endl;
/* sleep adalah system call atau fungsi library yang menghentikan
proses ini dalam detik
*/
sleep(1);
}
return 0;
}
-
Hasil
2. Gunakan g++ compiler untuk menjalankan
program di atas
$ g++ -o fork 1 fork 1.cpp
$ ./fork 1
3. Amati output yang dihasilkan
Analisa :
Pada program diatas bertujuan untuk melihat proses
parent dan proses child. Salah satu caranya
yaitu dengan melihat PID (Process Identifier) dan PPID (Parent Process
Identifier) dari proses. Untuk mendapatkan nilai PID dan PPID dapat dilakukan
dengan fungsi getpid() dan getppid() yang dideklarasikan pada unistd.h. kedua
fungsi tersebut akan mengembalikan nilai bertipe pid_t yang merupakan sebuah
signed integer yang menunjukkan PID. Dapat dilihat dengan menggunakan perintah
ps bahwa proses ./fork1 memiliki PID 9930 dan PPID adalah 2952 yang merupakan
proses bash. Selain itu, pada program ini juga digunakan fungsi getuid() untuk
mendapatkan id dari user yang menjalankan dan fungsi sleep() yang menghentikan
proses dalam detik.
Percobaan 2 : Membuat dua proses terus menerus dengan sebuah system
call fork()
1. Dengan
menggunakan editor vi, buatlah file fork2.cpp dan ketikkan program berikut:
#include <iostream>
using namespace std; #include <sys/types.h>
#include <unistd.h>
/* getpid() dan fork() adalah system call yg dideklarasikan
pada unistd.h.
Menghasilkan suatu nilai dengan type pid_t.
pid_t adalah type khusus untuk process id yg
ekuivalen dg int
*/
int main(void) {
pid_t childpid;
int x = 5;
childpid = fork();
while (1) {
cout << "This is process " << getpid() << endl;
cout << "x is " << x << endl;
sleep(1);
x++;
}
return 0;
}
Hasil:
2. Gunakan g++
compiler untuk menjalankan program di ats. Pada saat dijalankan, program tidak
akan pernah berhenti. Untuk menghentikan program tekan Ctrl+C.
$ g++ -o fork 2 fork 2.cpp
$ ./fork 2
Hasil :
3. Amati
output yang dihasilkan.
Analisa:
Pada Perintah
diatas bertujuan untuk membuat dua proses secara terus menerus menggunakan
system call fork(). Fork adalah suatu system call yang dapat membuat proses
baru. Proses asal yang melakukan fork disebut dengan parent process, sedangkan
proses baru yang dibuat setelah melakukan fork disebut dengan child process.
Nilai yang dikembalikan oleh fork adalah PID dari child process. Dapat dilihat
bahwa pada percobaan ini, yang merupakan child process adalah proses dengan PID
10461, sedangkan yang merupakan parent process adalah process dengan PID 10460.
Lalu, x berfungsi untuk menghitung berapa kali loop telah terjadi. Jika dilihat
dari urutan cetakannya, dapat dilihat bahwa walaupun mereka melakukan proses
yang sama, parent process selalu berjalan terlebih dahulu sebelum child
process. Program ini akan melakukan loop secara terus menerus tanpa henti.
Untuk memberhentikannya, maka harus dihentikan secara paksa dengan interupsi
menggunakan Ctrl+C
Percobaan 3: Membuat dua proses sebanyak lima kali
1. Dengan
menggunakan editor vi, buatlah file fork3.cpp dan ketikkan program berikut:
#include <iostream>
using namespace std; #include <sys/types.h>
#include <unistd.h>
/* getpid() dan fork()
adalah system call yg dideklarasikan pada unistd.h.
Menghasilkan suatu nilai dengan type pid_t.
pid_t adalah
type khusus untuk process id yg ekuivalen dg int
*/
int main(void) { pid_t childpid; childpid = fork();
for (int i = 0; i < 5; i++) {
cout << "This is process " << getpid() << endl; sleep(2);
}
return 0;
}
Hasil:
2. Gunakan g++
compiler untuk menjalankan program di atas
$ g++ -o fork 3 fork 3.cpp
$ ./fork 3
Hasil:
3. Amati output
yang dihasilkan
Analisa:
Pada Perintah
diatas hampir sama dengan program fork2, hanya saja bedanya pada program ini
loop yang dilakukan dibatasi hingga 5 kali saja, tidak infinite. Pada percobaan
ini, dapat dilihat bahwa yang merupakan child process adalah proses dengan PID 5827,
sedangkan yang merupakan parent process adalah proses dengan PID 5826. Selain
itu, disini terbukti kembali bahwa walaupun mereka melakukan proses yang sama,
parent process selalu berjalan terlebih dahulu sebelum process jika dilihat
dari urutan cetakannya.
Percobaan 4: Proses parent menunggu sinyal dari
proses child dengan sistem call wait
1. Dengan
menggunakan editor vi, buatlah fork4.cpp dan ketikkan program berikut:
#include <iostream>
using namespace std;
#include
<sys/types.h>
#include
<unistd.h>
#include
<sys/wait.h>
/* pid_t fork() dideklarasikan pada unistd.h.
pid_t adalah type khusus
untuk process id yg ekuivalen dg int
*/
int main(void)
{ pid_t child_pid; int status;
pid_t wait_result;
child_pid = fork();
if (child_pid == 0) {
/* kode ini hanya dieksekusi proses child */
cout <<
"I am a child and my pid = " << getpid() << endl; cout
<< "My parent is " << getppid() << endl;
/* keluar if akan menghentikan hanya proses child
*/
}
else if (child_pid > 0)
{
/* kode ini hanya mengeksekusi proses parent */
cout <<
"I am the parent and my pid =
" << getpid()
<< endl;
cout << "My child has pid = "
<< child_pid << endl;
}
else {
cout << "The
fork system call failed to create a new process" << endl;
exit(1);
}
/* kode ini dieksekusi baik oleh proses parent dan child */ cout <<
"I am a happy, healthy
process and my pid = "
<< getpid() << endl;
if (child_pid == 0) {
/* kode ini hanya dieksekusi oleh proses child */ cout <<
"I am a child and I am quitting work now!"
<< endl;
}
else {
/* kode ini hanya dieksekusi oleh proses parent */ cout << "I am a parent and I am going to wait for my
child" << endl;
do {
/* parent menunggu sinyal SIGCHLD mengirim tanda bahwa proses child diterminasi */
wait_result =
wait(&status);
} while (wait_result !=
child_pid);
cout << "I am a parent and I am
quitting." << endl;
}
return 0;
}
Hasil:
2. Gunakan g++
compiler untuk menjalankan program di atas
$ g++ -o fork 4 fork 4.cpp
$ ./fork 4
Hasil:
3. Amati output
yang dihasilkan
Analisa:
Pada
program-program sebelumnya proses child dan parent menjalankan baris yang sama,
maka pada program ini kedua proses tersebut menjalankan baris yang berbeda. Hal
ini dapat dilakukan dengan pengkondisian if..else pada hasil pengembalian
system call fork. Pada child process, fork akan mengembalikan nilai 0,
sedangkan pada parent process, fork akan mengembalikan nilai bilangan positif
berupa PID dari process child. Namun, jika process child gagal terbentuk, fork
akan mengembalikan nilai -1. Dengan mengetahui return value dari fork, maka
kita bisa membagi pengerjaan proses parent dan child menggunakan pengkondisian
if..else. Karena kita tahu bahwa parent process akan berjalan terlebih dahulu
sebelum child process, maka kita harus membuat parent process untuk berhenti
sementara hingga child process selesai berjalan. Disitulah kegunaan system call
wait() dibutuhkan. System call wait akan membuat proses parent berhenti
sementara dan menunggu hingga proses child selesai dan diterminasi. Setelah
proses child diterminasi system call wait akan mengembalikan nilai berupa PID
dari proses child yang diterminasi tersebut. Itulah mengapa pada program
diatas, wait dilakukan di dalam loop do..while, selama hasil return value dari
wait tidak sama dengan PID proses child, maka proses parent akan terus
melakukan waiting
Percobaan 5: Sistenm call fork/exec dan wait
mengeksekusi program bernama ls, menggunakan file executable /bin/ls dengan
satu parameter -l yang ekuivalen dengan ls -l
1. Dengan
menggunakan editor vi, buatlah fork5.cpp dan ketikkan program berikut:
#include <iostream>
using namespace std;
#include <sys/types.h> #include
<unistd.h>
#include <sys/wait.h>
/* pid_t
fork() dideklarasikan pada unistd.h.
pid_t adalah type khusus untuk process id yg
ekuivalen dg int
*/
int main(void) {
pid_t child_pid;
int status;
pid_t
wait_result;
child_pid = fork();
if (child_pid ==
0) {
/* kode ini hanya dieksekusi proses child */
cout <<
"I am a child and my
pid = " << getpid() << endl;
execl("/bin/ls", "ls", "-l", "/home", NULL);
/* jika execl berhasil kode ini tidak pernah
digunakan */ cout << "Could not execl file /bin/ls" << endl;
exit(1);
/* exit menghentikan hanya proses child */
}
else if (child_pid > 0) {
/* kode ini hanya mengeksekusi proses parent */ cout <<
"I am the parent and
my pid = " << getpid()
<< endl;
cout <<
"My child has pid = " << child_pid << endl;
}
else {
cout << "The fork system call failed to
create a new process" << endl;
exit(1);
}
/* kode ini hanya dieksekusi oleh proses parent karena child mengeksekusi dari “/bin/ls” atau keluar */
cout << "I am a happy, healthy process and my pid = "
<<
getpid() << endl;
if (child_pid
== 0) {
/* kode ini tidak
pernah dieksekusi */ printf("This code will never be executed!\n");
}
else {
/* kode ini hanya
dieksekusi oleh proses parent */ cout << "I am a parent and I am
going to wait for my
child" << endl;
do {
/* parent menunggu sinyal
SIGCHLD mengirim tanda bila proses child diterminasi */
wait_result =
wait(&status);
} while (wait_result != child_pid);
cout <<
"I am a parent and I am quitting." << endl;
}
return 0;
}
Hasil:
2. Gunakan g++
compiler untuk menjalankan program di atas
$ g++ -o fork 5 fork 5.cpp
$ ./fork 5
Hasil :
3. Amati output
yang dihasilkan
Analisa:
Pada program
ini akan melakukan forking dan proses child akan menjalankan perintah ls -l.
Hal ini dapat dilakukan dengan menjalankan system call execl pada proses child.
Execl merupakan system call yang berfungsi untuk mengeksekusi file. Pada kasus
ini, child process mengeksekusi perintah ls yang filenya berada di /bin/ls
dengan argument -l dan /home. Fungsi execl dapat dimasukkan banyak parameter.
Namun, parameter utama yang harus dimasukkan ada 3, yaitu path dari file yang
akan dieksekusi, argument perintah (bisa lebih dari satu), dan NULL (sebagai
penanda akhiran dari argument). System call execl akan mengganti process image
sebelumnya dengan process image yang baru. Sehingga jika execl berhasil
dijalankan, maka setelah execl selesai dijalankan oleh process child dan diterminasi,
proses child akan tetap berjalan. Itulah mengapa baris proses child dibawah
execl pada percobaan diatas tidak dijalankan.
Percobaan 6: Sistem call fork/exec dan wait
mengeksekusi program lain
1. Dengan
menggunakan editor vi, buatlah fork6.cpp dan ketikkan program berikut:
#include <iostream>
using namespace std;
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
/* pid_t
fork() dideklarasikan pada unistd.h.
pid_t adalah
type khusus untuk process id yg ekuivalen dg int
*/
int main(void) { pid_t chil d_pid; int status;
pid_t
wait_result;
child_pid = fork();
if (child_pid == 0) {
/* kode ini hanya dieksekusi proses child */
cout << "I am a child and my pid =
" << getpid() << endl;
execl("fork3",
"goose", NULL);
/* jika execl berhasil kode ini tidak
pernah digunakan */
cout <<
"Could not execl file fork3" << endl;
exit(1);
/* exit menghentikan hanya proses child */
}
else if (child_pid > 0) {
/* kode ini hanya mengeksekusi proses
parent */ cout << "I am the parent and my pid = " << getpid()
<< endl;
cout << "My child has pid = " << child_pid << endl;
}
else {
cout << "The fork system call failed to create a new process" << endl;
exit(1);
}
/* kode ini hanya dieksekusi oleh proses parent karena child mengeksekusi
dari “fork3” atau keluar */
cout <<
"I am a happy, healthy process and my pid = "
<< getpid() << endl;
if (child_pid == 0) {
/* kode ini tidak pernah dieksekusi
*/ printf("This code will never be executed!\n");
}
else {
/* kode ini hanya dieksekusi oleh proses parent */ cout << "I am a parent and I am going to wait for my
child"
<< endl;
do {
/* parent
menunggu sinyal SIGCHLD mengirim
tanda bila proses child diterminasi */
wait_result = wait(&status);
} while (wait_result != child_pid);
cout <<
"I am a parent and I am quitting." << endl;
}
return 0;
}
Hasil:
2. Gunakan g++
compiler untuk menjalankan program di atas
$ g++ -o fork 6 fork 6.cpp
$ ./fork 6
Hasil :
3. Amati output
yang dihasilkan
Analisa:
Pada program
ini, proses child mengeksekusi program lain (fork3) dengan menggunakan system
call execl. Pada percobaan diatas, proses dengan PID 6139 adalah proses parent,
sedangkan proses dengan PID 6140 adalah process child. Namun, saat proses child
menjalankan execl dan mengeksekusi fork3, proses dengan 6140 PID pada program fork3 akan menjadi proses parent
dan ia akan membuat proses child baru dengan PID 6141.
Percobaan 7: Melihat Manajemen Memory
1. Perhatikan
dengan perintah dmesg jumlah memori tersedia dan proses swapping
$ dmesg | more
Hasil :
Analisa:
Perintah dmesg
digunakan untuk mencetak dan mengontrol buffer ring kernel. Di dalam informasi
yang dicetak oleh dmesg, terdapat pula jumlah memori yang tersedia. Dapat
dilihat di atas bahwa jumlah memori yang tersedia ada 2907932 KB dari total
memori 3071544 KB.
2. Dengan
perintah free perhatikan jumlah memory “free”, “used”, “share”, dan “buffer”
$ free
Hasil :
Analisa :
Perintah free
akan menampilkan informasi tentang
memori dan swap dalam kilobyte (1 kilobyte).
3. Dengan
perintah dibawah ini apakah hasilnya sama dengan no 2?
$ cat /proc/meminfo
Hasil:
Analisa :
Hasil yang ditampilak oleh cat /proc/meminfo hampir
sama dengan hasil pada free. Hanya saja bedanya cat /proc/meminfo menampilkan
lebih banyak informasi daripada free.
4. Gunakan perintah di bawah ini
$ ls
–lR /.
Hasil :
Analisa:
Perintah ls
-lR /. menampilkan semua direktori dan file yang ada pada system
informasi. Karena banyaknya file yang ditampilkan, perintah tersebut akan
berjalan secara terus menerus tanpa henti
5. Perhatikan perubahan manajemen memory
$ Free
Hasil :
Sebelum
Sesudah
Analisa :
Dapat dilihat bahwa memori yang
“free” menjadi berkurang, memori yang “available” berkurang, dan penggunaan
memori shared dan buff/cache bertambah, sedangkan besar swap “used” bertambah
dan swap “free” menjadi berkurang.
6. Jalankan sebuah program, misalnya
open Office. Perhatikan perubahan manajemen memori.
$ free
Hasil :
Analisa :
Setelah dijalankan open Office,
memori yang digunakan dan shared memori menjadi lebih besar dan memori
available berkurang juga. Selain itu, beberapa swap mulai digunakan.
7. Dengan perintah ps bagaimana penggunaan
memory untuk setiap proses diatas?
$ ps -uax
Hasil :
Analisa :
Perintah
ini sangat berguna untuk menunjukkan bagaimana penggunaan memori berubah secara
dinamis dan bagaimana proses individu menggunakan memori.
LATIHAN :
1.
Ubahlah
program fork5.cpp pada percobaan 5 untuk mengeksekusi perintah yang ekuivalen
dengan.
a.
ls-al
/etc.
b.
cat
fork2
c.
./fork2
2.
Informasi apa saja mengenai
manajemen memory yang ditampilkan pada perintah dmesg pada percobaan Anda?
Analisa :
Informasi yang ditampilkan
mengenai manajemen memori pada dmesg adalah banyaknya memori yang tersedia
beserta rincian penggunaan memori tersebut seperti kernel code, rwdata
(read-write), rodata (read-only), init, bss, reserved (memori cadangan), dan
cma-reserved.
3. Bagaimana informasi yang
ditampilkan dengan perintah free pada percobaan Anda?
Jawab:
Analisa :
Pada
perintah diatas informasi yang ditampilkan dengan perintah free adalah:
o Total: Menampilkan
total memori yang ada computer.
o Used: Menampilkan total memori yang
sedang digunakan. Rumus perhitungannya adalah Total – (Free + Buffers + Cache).
o Free: Menampilkan total memori yang
tidak digunakan.
o Shared: Menampilkan total memori yang
digunakan oleh buffers, page cache, dan slabs.
o Available: Menampilkan perkiraan dari
total memori yang siap digunakan untuk menjalankan program baru tanpa
dilakukannya swapping.
4.
Apa
isi file /proc/meminfo pada
percobaan yang Anda lakukan?
Jawab :
Ada banyak sekali informasi yang
ditampilkan pada meminfo, diantaranya sebagai berikut :
5.
Berapa
besar memory yang digunakan setelah percobaan 7 dengan perintah ps –uax?
Jawab :
Banyak memori yang digunakan
menurut ps -uax adalah sebesar 0.1%
6. Lakukan hal yang
sama dengan percobaan 7 untuk
melihat perubahan memory setelah dilakukan beberapa proses
pada shell. Tentukan perintah yang dilakukan misalnya membuka browser dan
perhatikan hal-hal berikut:
a.
Informasi
apa saja yang ditampilkan dengan perintah free?
Analisa :
Informasi yang ditampilkan dengan
perintah free adalah:
· Total: Menampilkan
total memori yang ada computer.
· Used: Menampilkan total memori yang
sedang digunakan. Rumus perhitungannya adalah Total – (Free + Buffers + Cache).
· Free: Menampilkan total memori yang
tidak digunakan.
· Shared: Menampilkan total memori yang
digunakan oleh buffers, page cache, dan slabs.
· Available: Menampilkan perkiraan dari
total memori yang siap digunakan untuk menjalankan program baru tanpa
dilakukannya swapping.
b. Informasi apa saja yang disimpan file /proc/meminfo?
Jawab:
Berikut adalah informasi yang disimpan dalam
/proc/meminfo:
c. Berapa besar kapasitas memory
total?
Jawab:
Kapasitas memori total adalah 2035284 kB.
d. Berapa kapasitas memory yang sudah terpakai?
Jawab:
Kapasitas memori yang sudah terpakai adalah 712808
kB.
e. Berapa kapasitas memory yang
belum terpakai?
Jawab:
Kapasitas memori yang belum terpakai adalah 510540
kB.
f. Berapa kapasitas memory yang
digunakan sharing beberapa proses?
Jawab:
Kapasitas memori yang digunakan
sharing beberapa proses adalah 1712 kB.
g. Berapa kapasitas buffer cache?
Jawab:
Kapasitas buffer cache adalah
755504 kB.
KESIMPULAN:
System calls adalah cara terprogram
di mana program komputer meminta layanan dari kernel sistem operasi tempat
dijalankannya. System calls menyediakan antarmuka antara proses dan sistem
operasi. Pada praktikum kali ini, kita melakukan 3 macam system calls, yaitu
system calls fork, execl, dan wait. System calls fork adalah system calls yang
dapat membuat proses baru dengan menduplikasi proses. Proses baru disebut
sebagai proses child. Proses yang memanggilnya disebut sebagai proses parent.
System calls execl berfungsi untuk mengekseskusi sebuah file dengan memberi
parameter berupa path file dan argumen-argumen perintah file. Sistem call execl
meletakkan program executable baru ke memory dan mengasosiasikannya dengan
proses saat itu. Sedangkan system calls wait adalah ystem call yang digunakan
untuk menunggu perubahan status pada child process yang dipanggil, dan
mendapatkan informasi tentang child process yang statusnya telah berubah. Linux
mengimplementasikan sistem virtual memory demand-paged. Proses mempunyai besar
memory virtual yang besar.
Pada virtual memory dilakukan
transfer page antara disk dan memory fisik. Jika tidak terdapat cukup memory
fisik, kernel melakukan swapping beberapa page lama ke disk. Jika memory total
page lebih dari memory fisik yang tersedia, kernel lebih banyak melakukan
swapping dibandingkan eksekusi kode program, sehingga terjadi thrashing dan
mengurangi utilitas.
Perbedaan antara proses parent
dan proses child adalah mempunyai pid yang berbeda, pada proses parent, fork()
menghasilkan pid dari proses child jika sebuah proses child dibuat, membedakan
copy dari semua data, termasuk variable dengan current value dan stack,
membedakan program counter yang menunjukkan eksekusi berikutnya meskipun
awalnya keduanya mempunyai nilai yang sama tetapi setelah itu berbeda, dan
setelah fork, kedua proses tersebut tidak menggunakan variable bersama.
Komentar
Posting Komentar