名前はpipe()
です。注意:UNIXのファイル記述子は、両方のプロセスでfork()
とexecve()
の後に開いたままです!したがって、pipe()
を使用してファイル記述子のペアを取得し、bashのecho >&FD
を使用してfdに書き込むことができます。FD
はファイル記述子番号です。
これは、非常に簡単で、簡単で、私が推測するものよりも少ないリソースを使用します。 select()
の使用は問題ありません。ただブロックしないでくださいread()
私のサンプルではありますが、select()
はpfds[0]
です。
サンプルプログラム( 'hello work、my pid:XXX'を送信する10のbashプロセスがプロセスを起動する間に1秒待っています)サンプルはすべての子に1つのパイプしか使用しませんでした。 。それについては実際には、私はは)(サンプル下記の注を参照)、それをお勧めしません:
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
int main(int argc, char **argv) {
int pfds[2];
pid_t p;
assert(0 == pipe(pfds));
p = fork();
if (p == 0) {
unsigned int i;
char str_fd[3]; char *env[] = {NULL};
char *args[] = { "/bin/bash", "-c", "echo >&$1 hello world, my pid: $$"
, "-s", str_fd, NULL};
snprintf(str_fd, 3, "%d", pfds[1]);
str_fd[2] = 0;
for (i = 0; i < 10; i++) {
p = fork();
if(0 == p) {
assert(0 ==
execve("/bin/bash", (char *const*)args
, (char *const*)env));
} else if (0 > p) {
perror("fork");
exit(1);
} else {
wait(NULL);
}
sleep(1);
}
} else if(p > 0) {
char *buf = malloc(100);
ssize_t sz;
printf("fd is %d, <hit Ctrl+C to exit>\n", pfds[1]);
while(0 < (sz = read(pfds[0], buf, 100))) {
buf[99] = 0;
printf("received: '%s'\n", buf);
}
free(buf);
if (0 == sz) {
fprintf(stderr, "EOF!");
} else {
perror("read from bash failed");
}
wait(NULL);
} else {
perror("fork failed");
exit(1);
}
return 0;
}
サンプルプログラムの出力:
$ gcc test.c && ./a.out
fd is 4, <hit Ctrl+C to exit>
received: 'hello world, my pid: 779
'
received: 'hello world, my pid: 780
'
received: 'hello world, my pid: 781
'
received: 'hello world, my pid: 782
'
received: 'hello world, my pid: 783
'
received: 'hello world, my pid: 784
'
received: 'hello world, my pid: 785
'
received: 'hello world, my pid: 786
'
received: 'hello world, my pid: 787
'
received: 'hello world, my pid: 788
'
作品は、bashsは「送信Hello Worldの、私をpid:親プロセスにXXX \ n 'すべて1つのパイプを使用しています:-)。
デモプログラム(POSIXセマンティクスを使ってOKで、LinuxとMacOS Xでテストしたはずです)のように動作するようですが、子プロセスごとにpipe()
を使用することをお勧めします。これにより、問題が少なくなり、一度に複数の子プロセスを実行することも可能になります。 select()
またはepoll()
(多くの子プロセスがある場合)はあなたの友人です。
pipe()
は、特にbashと比較して非常に安いので、私は間違いなく1つ以上の子供のために同じパイプを使用しません。
+1データグラムソケットは、Accept()を混乱させる必要がないためです。また、マニュアルページによれば、Unixドメインのデータグラムソケットは信頼できるものですが、UDPソケットは信頼できません。それはまさに私が探していたものです。ありがとうございました。 –
私は単純なパイプの使用は、リソースが少なくて済み、ファイルシステムに触れず、(sendmsg()/ sendto()のために外部プログラムを使わなくても)bashで完全に実行できるので、 –
ソケットファイル名が宛先アドレスであるので、ヘルパープログラムは必要でないかもしれません(私は試していません)ので、 'echo" abc "> socket'で十分です。 –