Berbagi teknologi

Server reaktor konkurensi tinggi [sedang]

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

4. Pengendalian proses dan sinkronisasi proses

1. Sinyal

1.1 Konsep dasar sinyal

Sinyal (sinyal) adalah interupsi perangkat lunak. Ini adalah metode transmisi pesan antar proses. Ini digunakan untuk memberi tahu proses bahwa suatu peristiwa telah terjadi, tetapi tidak dapat meneruskan data apa pun ke proses.

Ada banyak alasan mengapa sinyal dihasilkan di Shell, yang dapat Anda gunakankillDankillallPerintah untuk mengirim sinyal:

kill -信号的类型 进程编号
killall -信号的类型 进程名
  • 1
  • 2

1.2 Jenis sinyal

nama sinyalnilai sinyalTindakan pemrosesan defaultAlasan untuk memberi isyarat
MENDESAH1ATerminal hang atau proses kontrol berhenti
TANDA TANGAN2AInterupsi keyboard Ctrl+c
SIGQUIT3CTombol escape pada keyboard ditekan
SIGIL4CInstruksi ilegal
PERANGKAP SIG5Cinstruksi titik henti
SIGABRT6CSinyal batalkan yang dikeluarkan oleh batalkan(3)
SIGBUS7Ckesalahan bus
SIGFPE8Cpengecualian titik mengambang
SIGKILL9Akill -9 mematikan proses, sinyal ini tidak dapat ditangkap dan diabaikan
SIGUSR110ASinyal yang ditentukan pengguna 1
SIGSEGV11CReferensi memori tidak valid (array di luar batas, operasi penunjuk nol)
SIGUSR212ASinyal yang ditentukan pengguna 2
PIPA SIG13AMenulis data ke pipa tanpa proses membaca
SIGALRM14ASinyal jam alarm, sinyal dikirim oleh fungsi alarm()
Istilah SIG15ASinyal terminasi, sinyal yang dikirim secara default
SIGSTKFLT16Akesalahan tumpukan
SIGCHLD17BDipancarkan ketika proses anak berakhir
KONTAK SIGNAL18DLanjutkan proses yang dihentikan
BERHENTI MENDAFTAR19DHentikan proses
SIGTSTP20DTerminal tekan tombol berhenti
MENDAFTAR21DProses latar belakang meminta untuk membaca terminal
SIGTTOU22DProses latar belakang meminta untuk menulis ke terminal
SIGURG23BDeteksi kondisi darurat (soket)
SIGX CPU24CBatas waktu CPU terlampaui
SIGXFSZ25CBatas ukuran file terlampaui
SIGVTALRM26Asinyal jam virtual
SIGPROF27AAnalisis sinyal jam
SIGWINCH28BPerubahan ukuran jendela
SIGPOLL29BJajak Pendapat (Sys V)
SIGPWR30Akegagalan listrik
SIGSYS31CPanggilan sistem ilegal

Tindakan default A adalah menghentikan proses.

Tindakan default B adalah mengabaikan sinyal ini.

Tindakan default C adalah menghentikan proses dan melakukan dump image kernel.

Tindakan default D adalah menghentikan proses, dan program yang memasuki status dihentikan dapat terus dijalankan.

1.3 Pemrosesan sinyal

Ada tiga cara proses menangani sinyal:

  1. Operasi default sistem digunakan untuk menangani sinyal ini. Operasi default sebagian besar sinyal adalah menghentikan proses.
  2. Mengatur fungsi pemrosesan interupsi. Setelah menerima sinyal, fungsi tersebut akan menanganinya.
  3. Abaikan suatu sinyal dan jangan lakukan apa pun terhadap sinyal tersebut seolah-olah hal itu tidak pernah terjadi.

signal()Fungsi dapat mengatur bagaimana program menangani sinyal.

Deklarasi fungsi:

#include <signal.h>

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
  • 1
  • 2
  • 3
  • 4

Deskripsi Parameter:

  • sig:Tentukan sinyal yang akan ditangkap.
  • func : Penunjuk ke fungsi pemrosesan sinyal. Fungsi pemrosesan perlu menerima parameter bilangan bulat, yaitu nomor sinyal yang ditangkap.
  1. SIG_DFL Makro :SIG_DFL mewakili metode pemrosesan sinyal default.menggunakanSIG_DFLsebagaisignalParameter kedua dari fungsi tersebut menunjukkan bahwa metode pemrosesan default sistem digunakan untuk sinyal.
  2. SIG_IGN Makro :SIG_IGN berarti mengabaikan sinyal.menggunakanSIG_IGNsebagaisignal Parameter kedua dari fungsi tersebut menunjukkan bahwa ketika proses menerima sinyal, proses tersebut akan mengabaikannya dan tidak melakukan pemrosesan apa pun. Hal ini dapat mencegah proses dihentikan atau diinterupsi secara tidak terduga dalam keadaan tertentu.
  3. SIG_ERR:SIG_ERR Makro digunakan untuk menunjukkan kesalahan.itu tidak sepertisignalParameter kedua dari fungsi tersebut digunakan sebagaisignal Nilai kembalian fungsi menunjukkan bahwa panggilan gagal.jikasignalJika panggilan ke fungsi gagal, fungsi tersebut akan kembaliSIG_ERR .Ini biasanya digunakan untuk mendeteksi dan memprosessignalKesalahan dalam pemanggilan fungsi.

gambar-20240709113614147

gambar-20240709113230874

gambar-20240709113240944

1.4 Apa kegunaan sinyal?

Program layanan berjalan di latar belakang. Jika Anda ingin menghentikannya, mematikannya bukanlah ide yang baik, karena ketika proses dihentikan, ia mati secara tiba-tiba dan tidak ada pekerjaan setelahnya yang diatur.

Jika Anda mengirim sinyal ke program layanan, setelah menerima sinyal, program layanan memanggil suatu fungsi dan menulis kode akibatnya dalam fungsi tersebut, dan program dapat keluar secara terencana.

Mengirimkan sinyal 0 ke program layanan dapat mendeteksi apakah program tersebut hidup.

gambar-20240709135336848

1.5 Mengirim sinyal

Sistem operasi Linux menyediakan kill Dankillall Perintah tersebut mengirimkan sinyal ke programkill() Fungsi perpustakaan mengirimkan sinyal ke proses lain.

Deklarasi fungsi:

int kill(pid_t pid, int sig);
  • 1

kill() Fungsi ini mengambil parametersig Sinyal yang ditentukan diteruskan ke parameterpid proses yang ditentukan.

parameter pid Ada beberapa situasi:

  1. pid > 0 Lewati sinyal ke proses sebagaipid proses.
  2. pid = 0 Meneruskan sinyal ke semua proses dalam grup proses yang sama dengan proses saat ini. Hal ini sering digunakan oleh proses induk untuk mengirim sinyal ke proses anak.
  3. pid < -1 Lewati sinyal ke ID grup proses|pid| dari semua proses.
  4. pid = -1 Meneruskan sinyal ke semua proses yang memiliki izin untuk mengirimkan sinyal, tetapi tidak ke proses yang mengirimkan sinyal.

2. Penghentian proses

Ada 8 cara untuk menghentikan suatu proses, 5 diantaranya merupakan penghentian normal, yaitu:

  1. ada main() Untuk fungsireturn kembali;
  2. Dipanggil dalam fungsi apa pun exit() fungsi;
  3. Dipanggil dalam fungsi apa pun _exit() atau_Exit() fungsi;
  4. Thread terakhir dimulai dari rutinitas startupnya (fungsi utama thread) dengan return kembali;
  5. Dipanggil di thread terakhir pthread_exit() kembali;

Ada tiga cara untuk mengakhiri secara tidak normal, yaitu:

  1. transfer abort() fungsi dibatalkan;
  2. Sebuah sinyal diterima;
  3. Thread terakhir menanggapi permintaan pembatalan.

2.1 Status penghentian proses

ada main() Dalam fungsinya,return Nilai yang dikembalikan adalah status penghentian, jika tidakreturn pernyataan atau panggilanexit(), maka status penghentian proses adalah 0.

Di shell, lihat status penghentian proses:

echo $?
  • 1

3 fungsi untuk menghentikan proses secara normal (exit() Dan_Exit() ditentukan oleh ISO C,_exit() ditentukan oleh POSIX):

void exit(int status);
void _exit(int status);
void _Exit(int status);
  • 1
  • 2
  • 3

status Status penghentian proses.

gambar-20240709143530327

gambar-20240709143615950

2.2 Masalah pelepasan sumber daya

  • return Menunjukkan bahwa ketika fungsi kembali, destruktor objek lokal akan dipanggil.main() dalam fungsireturn Penghancur objek global juga disebut.
  • exit() Menunjukkan untuk menghentikan proses, destruktor objek lokal tidak akan dipanggil, hanya destruktor objek global yang akan dipanggil.
  • _exit() Dan_Exit() Keluar secara langsung dan tidak ada pekerjaan pembersihan yang akan dilakukan.

2.3 Fungsi penghentian proses

Prosesnya tersedia atexit() Registrasi fungsi mengakhiri fungsi (hingga 32), fungsi-fungsi ini akanexit() Dipanggil secara otomatis.

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

exit() Urutan pemanggilan fungsi terminasi dibalik sejak saat registrasi.

gambar-20240709143824286

gambar-20240709143830549

3. Panggil program yang dapat dieksekusi

3.1 fungsi sistem()

system()Fungsi ini menyediakan metode sederhana untuk mengeksekusi program, meneruskan program dan parameter yang perlu dieksekusi sebagai string.system()Hanya berfungsi.

Deklarasi fungsi:

int system(const char * string);
  • 1

system()Nilai kembalian dari fungsi tersebut lebih merepotkan.

  1. Jika program yang dijalankan tidak ada,system()Fungsi ini mengembalikan bukan nol;
  2. Jika eksekusi program berhasil dan status eksekusi program yang dijalankan adalah 0,system()Fungsi ini mengembalikan 0;
  3. Jika eksekusi program berhasil dan status penghentian program yang dijalankan bukan 0,system()Fungsi ini mengembalikan bukan nol.

3.2 keluarga fungsi eksekutif

execKeluarga fungsi menyediakan cara lain untuk memanggil program (biner atau skrip shell) dalam suatu proses.

execKeluarga fungsi dideklarasikan sebagai berikut:

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Melihat

  1. Jika eksekusi program gagal, -1 dikembalikan secara langsung, dan alasan kegagalan disimpanerrnotengah.
  2. Nomor proses dari proses baru sama dengan proses asli, namun proses baru menggantikan segmen kode, segmen data, dan tumpukan proses asli.
  3. Jika eksekusi berhasil, fungsi tersebut tidak akan kembali jika berhasil dipanggil di program utamaexecSetelah itu program yang dipanggil akan menggantikan program pemanggil, yaituexecTidak ada kode setelah fungsi akan dijalankan.
  4. Dalam perkembangan sebenarnya, yang paling umum digunakan adalahexecl()Danexecv(), yang lain jarang digunakan.

4. Buat sebuah proses

4.1 Linux memproses 0, 1 dan 2

Semua proses di seluruh sistem Linux berada dalam struktur pohon.

  • **Proses No. 0 (proses sistem)** adalah nenek moyang semua proses. Ini menciptakan proses No. 1 dan No. 2.
  • **Proses No. 1 (systemd)** bertanggung jawab untuk melakukan inisialisasi kernel dan konfigurasi sistem.
  • **Proses No. 2 (kthreadd)** bertanggung jawab atas penjadwalan dan pengelolaan semua thread kernel.

menggunakanpstreeAnda dapat melihat pohon proses dengan perintah:

pstree -p 进程编号
  • 1

4.2 Identifikasi proses

Setiap proses memiliki ID proses unik yang diwakili oleh bilangan bulat non-negatif. Meskipun unik, ID proses dapat digunakan kembali. Ketika suatu proses dihentikan, ID prosesnya menjadi kandidat untuk digunakan kembali. Linux menggunakan algoritma penggunaan kembali yang tertunda sehingga ID dari proses yang baru dibuat berbeda dengan ID yang digunakan oleh proses yang baru saja dihentikan. Hal ini mencegah proses baru disalahartikan sebagai proses yang dihentikan menggunakan ID yang sama.

Fungsi untuk mendapatkan ID proses:

pid_t getpid(void);    // 获取当前进程的ID。
pid_t getppid(void);   // 获取父进程的ID。
  • 1
  • 2

4.3 fungsi garpu()

Proses yang ada dapat memanggilfork()Fungsi menciptakan proses baru.

Deklarasi fungsi:

pid_t fork(void);
  • 1

Bergantung padafork()Proses baru yang dibuat disebut proses anak.

fork() Fungsi ini dipanggil sekali tetapi kembali dua kali. Perbedaan antara kedua return tersebut adalah nilai return dari proses anak adalah 0, sedangkan nilai return dari proses induk adalah ID proses dari proses anak yang baru dibuat.

Proses anak dan proses induk terus dijalankanfork()Kode setelah itu, Proses anak adalah salinan dari proses induk. Proses anak memiliki salinan ruang data, heap, dan tumpukan proses induk (catatan: proses anak memiliki salinan, tidak dibagikan dengan proses induk).

fork()Setelah itu, urutan eksekusi proses induk dan anak tidak ditentukan.

gambar-20240709221535371

gambar-20240709221546617

4.4 Dua kegunaan fork()

  1. Proses induk ingin menyalin dirinya sendiri, lalu proses induk dan proses anak masing-masing mengeksekusi kode yang berbeda.Penggunaan ini sangat umum dalam program layanan jaringan. Proses induk menunggu permintaan koneksi klien. Ketika permintaan tiba, proses induk memanggilfork(), biarkan proses anak menangani permintaan ini, sementara proses induk terus menunggu permintaan koneksi berikutnya.
  2. Proses ingin mengeksekusi program lain.Penggunaan ini sangat umum di shell, dari mana proses anak dimulaifork()Dipanggil segera setelah kembaliexec

4.5 File bersama

fork()Salah satu fiturnya adalah deskriptor file yang dibuka dalam proses induk akan disalin ke proses anak, dan proses induk serta proses anak berbagi offset file yang sama.

Jika proses induk dan proses anak menulis ke file yang ditunjuk oleh deskriptor yang sama tanpa sinkronisasi apa pun, outputnya mungkin tercampur satu sama lain.

gambar-20240709222929369

gambar-20240709222803641

Pada titik ini Anda dapat melihat bahwa hanya ada 100.000 baris data.

gambar-20240709222853769

gambar-20240709223236254

Saat ini, seharusnya ada 200.000 baris data. Kurangnya satu baris mungkin karena operasi penulisan file tidak bersifat atomik, jika tidak ada mekanisme sinkronisasi, dua proses mungkin mencoba menulis bagian file yang berbeda secara bersamaan. menyebabkan penulisan gagal.

4.6 fungsi vfork()

vfork()Pemanggilan fungsi dan nilai kembalian sama denganfork()Sama, namun semantiknya berbeda.

vfork()Fungsi tersebut digunakan untuk membuat proses baru yang tujuannya adalahexecSebuah program baru yang tidak menyalin ruang alamat proses induk karena proses anak langsung memanggilexec , sehingga ruang alamat proses induk tidak akan digunakan. Jika proses anak menggunakan ruang alamat dari proses induk, hasil yang tidak diketahui mungkin terjadi.

vfork()Danfork()Perbedaan lainnya adalah:vfork()Pastikan proses anak berjalan terlebih dahulu dan panggil proses tersebut dalam proses anakexecatauexitKemudian proses induk melanjutkan operasi.

5. Proses zombie

Dalam sistem operasi, proses zombie mengacu pada proses anak yang telah dihentikan namun proses induknya belum membaca status keluarnya. Meskipun proses zombie tidak lagi berjalan, proses ini masih menempati entri dalam tabel proses sehingga kernel dapat menyimpan informasi status keluar proses (seperti ID proses, status keluar, dll.) hingga proses induk membaca informasi ini.

5.1 Penyebab proses zombie

Jika proses induk keluar sebelum proses anak, proses anak akan di-host oleh proses 1 (ini juga merupakan cara untuk membiarkan proses berjalan di latar belakang).

Jika proses anak keluar sebelum proses induk, dan proses induk tidak memproses informasi keluar dari proses anak, maka proses anak akan menjadi proses zombie.

5.2 Bahaya dari proses zombie

Kernel menyimpan struktur data untuk setiap proses anak, termasuk nomor proses, status terminasi, waktu CPU yang digunakan, dll. Jika proses induk memproses informasi keluar dari proses anak, kernel akan melepaskan struktur data ini. Jika proses induk tidak memproses informasi keluar dari proses anak, kernel tidak akan melepaskan struktur data ini, dan nomor proses dari proses anak akan selalu terisi. Jumlah proses yang tersedia dalam sistem terbatas. Jika proses zombie dihasilkan dalam jumlah besar, sistem tidak akan dapat menghasilkan proses baru karena tidak ada nomor proses yang tersedia.

5.3 Metode untuk menghindari proses zombie

  1. Menangani sinyal SIGCHLD : Ketika proses anak keluar, kernel akan mengirimkan sinyal SIGCHLD ke proses induk.Jika proses induk menggunakansignal(SIGCHLD, SIG_IGN)Beri tahu kernel bahwa ia tidak tertarik dengan keluarnya proses anak, dan struktur datanya akan segera dirilis setelah proses anak keluar.
  2. menggunakanwait()/waitpid()fungsi: Proses induk menunggu hingga proses anak selesai dengan memanggil fungsi-fungsi ini dan memperoleh status keluarnya, sehingga melepaskan sumber daya yang ditempati oleh proses anak.
pid_t wait(int *stat_loc); 
pid_t waitpid(pid_t pid, int *stat_loc, int options); 
pid_t wait3(int *status, int options, struct rusage *rusage); 
pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
  • 1
  • 2
  • 3
  • 4

Nilai yang dikembalikan adalah jumlah proses anak.

stat_loc Apakah informasi tentang penghentian proses anak:

a) Jika diakhiri secara normal, makro WIFEXITED(stat_loc) Kembalikan benar, makroWEXITSTATUS(stat_loc) Status penghentian dapat diperoleh;

b) Jika berakhir secara tidak normal, makro WTERMSIG(stat_loc) Mendapat sinyal untuk menghentikan proses.

gambar-20240709230911352

gambar-20240709231034423

gambar-20240709231050581

gambar-20240709231124375

gambar-20240709231140813

Jika proses induk sedang sibuk, Anda dapat menangkapnya SIGCHLD Sinyal, disebut dalam fungsi pemrosesan sinyalwait()/waitpid()

gambar-20240709231439475

gambar-20240709231422927

6.Beberapa proses dan sinyal

[Kirim sinyal antar proses](##1.5 Kirim sinyal)

Dalam program layanan multiproses, jika subproses menerima sinyal keluar, subproses akan keluar dengan sendirinya.

Jika proses induk menerima sinyal keluar, maka proses tersebut harus mengirimkan sinyal keluar ke semua proses anak dan kemudian keluar sendiri.

gambar-20240711222919564

gambar-20240711222900141

gambar-20240711223111481

7. Memori bersama

Multi-thread berbagi ruang alamat suatu proses,Jika beberapa thread perlu mengakses memori yang sama, gunakan saja variabel global.

Dalam beberapa proses, ruang alamat setiap proses bersifat independen dan tidak dibagikan.Jika beberapa proses perlu mengakses memori yang sama, variabel global tidak dapat digunakan, hanya memori bersama yang dapat digunakan.

Memori Bersama memungkinkan banyak proses (tidak diperlukan hubungan darah antar proses) untuk mengakses ruang memori yang sama. Ini adalah cara paling efektif untuk berbagi dan mentransfer data antar beberapa proses. Proses dapat menghubungkan memori bersama ke ruang alamatnya sendiri. Jika satu proses memodifikasi data di memori bersama, data yang dibaca oleh proses lain juga akan berubah.

Memori bersama tidak menyediakan mekanisme kunci, artinya, ketika suatu proses membaca/menulis memori bersama, hal ini tidak menghalangi proses lain untuk membaca/menulisnya.Jika Anda ingin mengunci baca/tulis memori bersama, Anda dapat menggunakan semaphore . Linux menyediakan serangkaian fungsi untuk mengoperasikan memori bersama.

7.1 fungsi shmget

Fungsi ini digunakan untuk membuat/memperoleh memori bersama.

 int shmget(key_t key, size_t size, int shmflg);
  • 1
  • kunci Nilai kunci dari memori bersama adalah bilangan bulat (typedef unsigned int key_t), umumnya dalam heksadesimal, misalnya 0x5005, kunci dari kenangan bersama yang berbeda tidak boleh sama.
  • ukuran Ukuran memori bersama, dalam byte.
  • sempoyongan Izin akses untuk memori bersama sama dengan izin untuk file, misalnya0666|IPC_CREAT Menunjukkan bahwa jika memori bersama tidak ada, buatlah.
  • nilai kembalian: Mengembalikan id memori bersama (bilangan bulat lebih besar dari 0) jika berhasil, -1 jika gagal (sistem memiliki memori yang tidak mencukupi dan tidak ada izin).

gambar-20240711224223200

gambar-20240711224212293

menggunakan ipcs -m Anda dapat melihat memori bersama sistem, termasuk: kunci, id memori bersama (shmid), pemilik, izin (perm), dan ukuran (byte).

menggunakan ipcrm -m 共享内存id Memori bersama dapat dihapus secara manual sebagai berikut:

gambar-20240711225202860

Catatan: Kontainer tidak dapat digunakan untuk tipe data di memori bersama, hanya tipe data dasar yang dapat digunakan.

7.2 fungsi shmat

Fungsi ini digunakan untuk menghubungkan memori bersama ke ruang alamat proses saat ini.

void *shmat(int shmid, const void *shmaddr, int shmflg);
  • 1
  • sempoyongan Bergantung padashmget() Pengidentifikasi memori bersama dikembalikan oleh fungsi.
  • shmaddr Tentukan lokasi alamat di mana memori bersama terhubung ke proses saat ini. Biasanya diisi dengan 0 agar sistem dapat memilih alamat memori bersama.
  • sempoyongan Bit bendera, biasanya diisi dengan 0.

Mengembalikan alamat awal memori bersama ketika panggilan berhasil, dan kembali ketika gagal. (void *)-1

7.3 fungsi shmdt

Fungsi ini digunakan untuk melepaskan memori bersama dari proses saat ini, yang setara dengan shmat() Operasi kebalikan dari suatu fungsi.

int shmdt(const void *shmaddr);
  • 1
  • shmaddr shmat() Alamat yang dikembalikan oleh fungsi.

Mengembalikan 0 jika panggilan berhasil dan -1 jika gagal.

7.4 fungsi shmctl

Fungsi ini digunakan untuk mengoperasikan memori bersama. Operasi yang paling umum digunakan adalah menghapus memori bersama.

int shmctl(int shmid, int command, struct shmid_ds *buf);
  • 1
  • sempoyongan shmget() Id memori bersama dikembalikan oleh fungsi.
  • memerintah Petunjuk pengoperasian memori bersama. Jika Anda ingin menghapus memori bersama, isilahIPC_RMID
  • buf Alamat struktur data yang mengoperasikan memori bersama. Jika Anda ingin menghapus memori bersama, isikan 0.

Mengembalikan 0 jika panggilan berhasil dan -1 jika gagal.

Catatan, gunakan root Memori bersama yang dibuat tidak dapat dihapus oleh pengguna biasa terlepas dari izin yang dibuat.

gambar-20240711230653886

gambar-20240711230522921

7.5 Antrian Melingkar

7.6 Antrian melingkar berdasarkan memori bersama

Mengembalikan 0 jika panggilan berhasil dan -1 jika gagal.

7.4 fungsi shmctl

Fungsi ini digunakan untuk mengoperasikan memori bersama. Operasi yang paling umum digunakan adalah menghapus memori bersama.

int shmctl(int shmid, int command, struct shmid_ds *buf);
  • 1
  • sempoyongan shmget() Id memori bersama dikembalikan oleh fungsi.
  • memerintah Petunjuk pengoperasian memori bersama. Jika Anda ingin menghapus memori bersama, isilahIPC_RMID
  • buf Alamat struktur data yang mengoperasikan memori bersama. Jika Anda ingin menghapus memori bersama, isikan 0.

Mengembalikan 0 jika panggilan berhasil dan -1 jika gagal.

Catatan, gunakan root Memori bersama yang dibuat tidak dapat dihapus oleh pengguna biasa terlepas dari izin yang dibuat.

[Gambar tautan eksternal sedang ditransfer...(img-v6qW3XRA-1720711279572)]

[Gambar tautan eksternal sedang ditransfer...(img-CG0tGAne-1720711279572)]Transfer gambar tautan eksternal gagal. Situs sumber mungkin memiliki mekanisme anti-leeching. Disarankan untuk menyimpan gambar dan mengunggahnya secara langsung.
Transfer gambar tautan eksternal gagal. Situs sumber mungkin memiliki mekanisme anti-leeching. Disarankan untuk menyimpan gambar dan mengunggahnya secara langsung.
Transfer gambar tautan eksternal gagal. Situs sumber mungkin memiliki mekanisme anti-leeching. Disarankan untuk menyimpan gambar dan mengunggahnya secara langsung.

7.5 Antrian Melingkar

7.6 Antrian melingkar berdasarkan memori bersama