GNU/Linux >> Belajar Linux >  >> Linux

Proses Linux – Tata Letak Memori, keluar, dan _keluar dari Fungsi C

Di bagian pertama dari rangkaian artikel proses Linux, kami membangun pemahaman tentang proses Linux dengan membahas tentang fungsi main(), dan fungsi C terkait lingkungan.

Pada artikel ini, kita akan membahas tentang tata letak memori dari suatu proses dan proses yang mengakhiri fungsi C.

Linux Processes Series:part 1, part 2 (this article), part 3

Tata Letak Memori suatu Proses

Tata letak memori suatu proses di Linux bisa sangat rumit jika kita mencoba menyajikan dan menjelaskan semuanya secara detail. Jadi, di sini kami hanya akan menyajikan hal-hal yang memiliki kepentingan signifikan saja.

Jika kita mencoba memvisualisasikan tata letak memori suatu proses, kita memiliki sesuatu seperti ini:

Mari kita jelaskan masing-masing komponen layout di atas satu per satu :

  • Argumen baris perintah dan variabel lingkungan disimpan di bagian atas tata letak memori proses di alamat yang lebih tinggi.
  • Kemudian muncul segmen tumpukan. Ini adalah area memori yang digunakan oleh proses untuk menyimpan variabel lokal dari fungsi dan informasi lain yang disimpan setiap kali suatu fungsi dipanggil. Informasi lain ini termasuk alamat pengirim yaitu alamat dari mana fungsi dipanggil, beberapa informasi tentang lingkungan pemanggil seperti register mesinnya dll disimpan di stack. Juga perlu disebutkan di sini adalah bahwa setiap kali fungsi rekursif dipanggil, bingkai tumpukan baru dihasilkan sehingga setiap set variabel lokal tidak mengganggu set lainnya.
  • Segmen heap adalah segmen yang digunakan untuk alokasi memori dinamis. Segmen ini tidak terbatas pada satu proses, melainkan dibagi di antara semua proses yang berjalan dalam sistem. Setiap proses dapat secara dinamis mengalokasikan memori dari segmen ini. Karena segmen ini digunakan bersama di seluruh proses, maka memori dari segmen ini harus digunakan dengan hati-hati dan harus dialokasikan segera setelah proses selesai menggunakan memori tersebut.
  • Seperti yang terlihat dari gambar di atas, tumpukan tumbuh ke bawah sedangkan tumpukan tumbuh ke atas.
  • Semua variabel global yang tidak diinisialisasi dalam program disimpan di segmen BSS. Setelah dieksekusi, semua variabel global yang tidak diinisialisasi diinisialisasi dengan nilai nol. Perhatikan bahwa BSS adalah singkatan dari 'Block Started by Symbol'.
  • Semua variabel global yang diinisialisasi disimpan dalam segmen data.
  • Terakhir, segmen teks adalah area memori yang berisi instruksi mesin yang dieksekusi CPU. Biasanya, segmen ini dibagikan di berbagai instance dari program yang sama yang sedang dieksekusi. Karena tidak ada gunanya mengubah instruksi CPU, maka segmen ini memiliki hak hanya baca.

Harap dicatat bahwa gambar di atas hanyalah representasi logis dari tata letak memori. Tidak ada jaminan bahwa pada sistem tertentu, tata letak memori dari suatu proses akan terlihat seperti ini. Selain itu, ada beberapa segmen lain untuk tabel simbol, informasi debug, dll .

Proses Mengakhiri Fungsi exit() dan _exit()

Fungsi-fungsi berikut dapat menyebabkan suatu proses dihentikan :

  1.  keluar(status) (sama seperti status pengembalian )
  2.  _keluar(status) atau _Keluar(status)

Perbedaan antara fungsi exit() dan fungsi _exit() adalah bahwa fungsi pertama mendukung beberapa pembersihan sebelum mengembalikan kontrol ke kernel sementara dua fungsi lainnya segera kembali ke kernel.

Fungsi _exit ditentukan oleh POSIX sementara _Exit ditentukan oleh ISO C. Selain itu, tidak ada perbedaan besar lainnya di antara keduanya.

Seperti yang sudah dibahas di atas, pembersihan adalah perbedaan utama antara exit() dan _exit(). Sebelum membuktikannya secara praktis, mari kita pahami fungsi lain ‘atexit()’.

Berikut prototypenya :

int atexit(void (*function)(void));

Seperti namanya, ini adalah panggilan sistem yang mengambil penunjuk fungsi dan mendaftarkan fungsi tertentu itu sebagai fungsi pembersihan untuk program ini. Ini berarti bahwa fungsi terdaftar akan dipanggil setiap kali suatu proses berakhir secara normal dan penghentian proses mendukung pembersihan.

Jika Anda melewati baris terakhir paragraf di atas sekali lagi, Anda akan melihat bahwa fungsi 'atexit' adalah bagian dari proses pembersihan yang membedakan antara fungsi exit() dan _exit(). Jadi, berikut adalah kode yang menggunakan fungsi atexit() dan exit()..

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

extern char **environ;

void exitfunc(void)
{
  printf("\n Clean-up function called\n");
}

int main(int argc, char *argv[])
{
  int count = 0;

  atexit(exitfunc);

  printf("\n");
  while(environ[count++] != NULL)
  {
    // Dos some stuff
  }

  exit(0);
}

Pada kode di atas, fungsi 'exitfunc()' didaftarkan ke kernel sebagai fungsi pembersihan dengan menggunakan fungsi atexit().

Ketika kode di atas dijalankan :

$ ./environ

Clean-up function called

Kami melihat bahwa fungsi pembersihan dipanggil.

JIKA kita mengubah panggilan dari exit() pada kode di atas menjadi _exit() :

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

extern char **environ;

void exitfunc(void)
{
  printf("\n Clean-up function called\n");
}

int main(int argc, char *argv[])
{
  int count = 0;

  atexit(exitfunc);

  printf("\n");
  while(environ[count++] != NULL)
  {
    // Dos some stuff
  }

  _exit(0);
}

Jika kita menjalankan program ini, kita melihat :

$ ./environ
$

Jadi kita melihat bahwa kali ini fungsi pembersihan 'exitfunc()' tidak dipanggil, yang menunjukkan perbedaan antara fungsi exit() dan _exit().


Linux
  1. Proses UNIX / Linux:C fork() Fungsi

  2. Linux:Temukan dan Bunuh Proses Zombie

  3. Ubuntu Linux:Memproses memori swap dan penggunaan memori

  1. Temukan Proses Berjalan Teratas berdasarkan Memori dan Penggunaan CPU Tertinggi di Linux

  2. Cara mendefinisikan dan menggunakan fungsi di Linux Shell Script

  3. Proses Linux – ID Proses, fork, execv, wait, waitpid Fungsi C

  1. Apa itu Proses Linux, Utas, Proses Ringan, dan Status Proses

  2. Ambil penggunaan CPU dan penggunaan memori dari satu proses di Linux?

  3. Buang memori proses linux ke file