09
その前 13
そして 21
これを行う方法でした(ここで 30
42
の 1 つです 54
を含む関数ファミリー 、 61
、 71
、 88
、 96
、および 101
)。現在、GNU C ライブラリでは、少なくとも Linux では 115
とにかく fork/exec 経由で実装されます。 Linux には 128
がありません システムコール。
131
を使用します (または 147
) 別のプロセスを起動します。これは親のクローンになります。子プロセスと親プロセスの両方で、実行は続行されますが、150
いずれの場合も異なる値を返し、区別できるようにします。その後、 168
のいずれかを使用できます 子プロセス内からの関数。
ただし、この問題に注意してください - 私のブログ投稿 (http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/) の 1 つから借用したテキスト:
<ブロック引用>別のプロセスを並行して実行し、exec() 呼び出しが成功したことを確認するための単純な標準準拠の方法 (または一般的に移植可能な方法) はないようです。問題は、いったん fork()d してから exec()d に成功すると、親プロセスと通信して exec() が成功したことを通知できないことです。 exec() が失敗した場合、(たとえばシグナルを介して) 親と通信できますが、成功を通知することはできません。親が exec() の成功を確認できる唯一の方法は、子を待つことです。プロセスを終了する (そして失敗の兆候がないことを確認する) 必要があり、それはもちろん並列実行ではありません。
つまり 178
の場合 成功すると、制御できなくなるため、元の (親) プロセスに成功を知らせることができません。
あなたの場合の問題である場合に備えて、この問題の潜在的な解決策:
<ブロック引用>[...] pipe() を使用してパイプを作成し、出力終了を close-on-exec に設定し、次に fork() (または vfork())、exec() を使用して、何か (おそらく errno) をexec() が失敗した場合 (_exit() を呼び出す前) にパイプします。親プロセスはパイプから読み取ることができ、exec() が成功した場合はすぐに入力の終わりを取得し、exec() が失敗した場合はデータを取得します。
(子プロセスが親プロセスよりも低い優先度で実行され、親がそこからの出力を待機する場合、このソリューションは優先度の逆転を引き起こす傾向があることに注意してください)。
183
もあります 上記および他の回答で述べたように、子実行可能ファイルの実行に失敗したことを検出する問題は解決されません。これは、いずれにしても fork/exec に関して実装されることが多く、191
ステージは失敗します。
201
/219
組み合わせはすでに述べましたが、 223
もあります 232
の代わりに使用できる関数ファミリー + 247
251
とより直接的に同等です .両方の可能性の例を次に示します:
#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));
}
}
あなたが書きました:
<ブロック引用><ブロック引用>現在実行中の image.system() ブロックを現在のプロセスに置き換えずに、ライブラリに新しいプロセスを作成したいのですが、良くありません。現在のプロセスを続行します。
コマンド呼び出しの後にアンパサンドを追加するだけです。例:266
あなたのプロセスはブロックされません!