posix_spawn
mungkin adalah solusi yang disukai saat ini.
Sebelum itu fork()
lalu execXX()
adalah cara untuk melakukan ini (di mana execXX
adalah salah satu dari exec
rangkaian fungsi, termasuk execl
, execlp
, execle
, execv
, execvp
, dan execvpe
). Di pustaka GNU C saat ini, setidaknya untuk Linux, posix_spawn
tetap diimplementasikan melalui fork/exec; Linux tidak memiliki posix_spawn
panggilan sistem.
Anda akan menggunakan fork()
(atau vfork()
) untuk meluncurkan proses terpisah, yang akan menjadi tiruan dari induknya. Dalam proses anak dan induk, eksekusi berlanjut, tetapi fork
mengembalikan nilai yang berbeda dalam kedua kasus memungkinkan Anda untuk membedakan. Anda kemudian dapat menggunakan salah satu dari execXX()
fungsi dari dalam proses anak.
Perhatikan, bagaimanapun, masalah ini - teks dipinjam dari salah satu posting blog saya (http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/):
Tampaknya tidak ada cara sederhana yang sesuai dengan standar (atau bahkan cara yang umumnya portabel) untuk menjalankan proses lain secara paralel dan memastikan bahwa panggilan exec() berhasil. Masalahnya adalah, setelah Anda fork()d dan kemudian berhasil exec()d Anda tidak dapat berkomunikasi dengan proses induk untuk memberi tahu bahwa exec() berhasil. Jika exec() gagal maka Anda dapat berkomunikasi dengan orang tua (melalui sinyal misalnya) tetapi Anda tidak dapat menginformasikan keberhasilan - satu-satunya cara orang tua dapat memastikan keberhasilan exec() adalah menunggu() untuk anak proses untuk menyelesaikan (dan periksa apakah tidak ada indikasi kegagalan) dan itu tentu saja bukan eksekusi paralel.
yaitu jika execXX()
berhasil, Anda tidak lagi memiliki kendali sehingga tidak dapat memberi sinyal keberhasilan pada proses (induk) asli.
Solusi potensial untuk masalah ini, jika ini merupakan masalah dalam kasus Anda:
[...] gunakan pipe() untuk membuat pipa, atur ujung keluaran menjadi close-on-exec, lalu fork() (atau vfork()), exec(), dan tulis sesuatu (mungkin errno) ke pipa jika exec() gagal (sebelum memanggil _exit()). Proses induk dapat membaca dari pipa dan akan segera mendapatkan input akhir jika exec() berhasil, atau beberapa data jika exec() gagal.
(Perhatikan bahwa solusi through ini cenderung menyebabkan pembalikan prioritas jika proses anak berjalan pada prioritas yang lebih rendah daripada induknya, dan induknya menunggu keluaran darinya).
Ada juga posix_spawn
seperti yang disebutkan di atas dan dalam jawaban lain, tetapi itu tidak menyelesaikan masalah mendeteksi kegagalan untuk mengeksekusi anak yang dapat dieksekusi, karena ini sering diimplementasikan dalam istilah fork/exec dan dapat mengembalikan kesuksesan sebelum exec()
tahap gagal.
fork
/exec
kombinasi sudah disebutkan, tetapi ada juga posix_spawn
rangkaian fungsi yang dapat digunakan sebagai pengganti fork
+ exec
dan lebih setara langsung dengan CreateProcess
. Berikut adalah contoh untuk kedua kemungkinan tersebut:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>
extern char **environ;
void test_fork_exec(void);
void test_posix_spawn(void);
int main(void) {
test_fork_exec();
test_posix_spawn();
return EXIT_SUCCESS;
}
void test_fork_exec(void) {
pid_t pid;
int status;
puts("Testing fork/exec");
fflush(NULL);
pid = fork();
switch (pid) {
case -1:
perror("fork");
break;
case 0:
execl("/bin/ls", "ls", (char *) 0);
perror("exec");
break;
default:
printf("Child id: %i\n", pid);
fflush(NULL);
if (waitpid(pid, &status, 0) != -1) {
printf("Child exited with status %i\n", status);
} else {
perror("waitpid");
}
break;
}
}
void test_posix_spawn(void) {
pid_t pid;
char *argv[] = {"ls", (char *) 0};
int status;
puts("Testing posix_spawn");
fflush(NULL);
status = posix_spawn(&pid, "/bin/ls", NULL, NULL, argv, environ);
if (status == 0) {
printf("Child id: %i\n", pid);
fflush(NULL);
if (waitpid(pid, &status, 0) != -1) {
printf("Child exited with status %i\n", status);
} else {
perror("waitpid");
}
} else {
printf("posix_spawn: %s\n", strerror(status));
}
}
Anda menulis:
Saya ingin membuat proses baru di perpustakaan saya tanpa mengganti image.system() yang mengeksekusi saat ini memblokir proses saat ini, itu tidak baik. Saya ingin melanjutkan proses saat ini.
Cukup tambahkan ampersand setelah panggilan perintah. Contoh:system("/bin/my_prog_name &");
Proses Anda tidak akan diblokir!