История изменений
Исправление vodz, (текущая версия) :
Таки и пришлось за вас всё писать:
#include <limits.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
/* Обработчик сигнала SIGCHLD */
static int *childs;
static int n;
static void
my_handler (int nsig)
{
int i;
for(;;) {
int pid = waitpid (-1, NULL, nsig == 0 ? 0 : WNOHANG);
if(pid < 0) {
if(errno == EINTR)
continue;
pid = 0;
}
if(pid == 0)
return;
for(i = 0; i < n; i++)
if(childs[i] == pid) {
childs[i] = 0;
if(nsig)
return;
}
}
}
static int get_int(const char *prompt)
{
long r;
char *e;
char inbuf[128];
for(;;) {
printf ("%s ", prompt);
if(fgets (inbuf, sizeof (inbuf), stdin) == NULL)
exit(0);
errno = 0;
r = strtol(inbuf, &e, 10);
if(e == inbuf || errno != 0 || *e != '\n' || r <= 0 || r > INT_MAX) {
fprintf(stderr, "Strange number '%s'\n", inbuf);
} else {
return r;
}
}
}
#define MSG_LENGHT 60
static void fill_msg(char *buf)
{
int i;
for(i = 0; i < MSG_LENGHT; i++) {
buf[i] = '!' + (rand() % ('~' - ' '));
}
buf[i] = '\n';
}
int
main (void)
{
int fd, i, m;
pid_t pid;
ssize_t r;
char *file_name;
int *p_pipefd;
int *PIP1;
char inbuf[MSG_LENGHT + 2];
n = get_int ("Сколько дочерних процессов создать");
m = get_int ("Количество циклов * количество процессов");
p_pipefd = malloc (n * 3 * sizeof (int));
childs = p_pipefd + n * 2;
for (i = 0; i < n; i++) {
PIP1 = p_pipefd + i * 2;
pipe (PIP1);
fd = snprintf (NULL, 0, "Foo_%d.txt", i + 1);
file_name = alloca (fd + 1);
snprintf (file_name, fd + 1, "Foo_%d.txt", i + 1);
(void) signal (SIGCHLD, my_handler);
if ((pid = fork ()) != 0) {
//PARENT
if(pid < 0) {
fprintf(stderr, "fork(): %s\n", strerror(errno));
return 1;
}
close (PIP1[0]);
childs[i] = pid;
} else {
//CHILD
int my_pid = getpid();
close (PIP1[1]);
fd = open (file_name, O_WRONLY | O_CREAT, 0666);
if (fd == -1) {
fprintf (stderr, "File '%s' create failed!\n", file_name);
return 1;
}
while ((r = read (PIP1[0], inbuf, MSG_LENGHT + 1)) > 0) {
write (fd, inbuf, r);
printf ("I (%d) receive: %s", my_pid, inbuf);
}
printf ("I (%d) exited\n", my_pid);
return 0;
}
}
for (i = 0; i < (n * m); i++) {
fd = rand () % n;
fill_msg(inbuf);
printf("Parent send to %d pid\n", childs[fd]);
write (p_pipefd[fd * 2 + 1], inbuf, MSG_LENGHT + 1);
}
for (i = 0; i < n; i++)
close (p_pipefd[i * 2 + 1]);
my_handler(0);
return 0;
}
$ ./a.out
Сколько дочерних процессов создать 3
Количество циклов * количество процессов 4
Parent send to 6624 pid
Parent send to 6623 pid
Parent send to 6623 pid
Parent send to 6624 pid
Parent send to 6624 pid
Parent send to 6624 pid
I (6623) receive: A07$Q:vFEr_`!f%w>/$U+%59T`7z+kwe6/%gczHCm)>**C<aQY8uwf0LaFa(
Parent send to 6623 pid
Parent send to 6624 pid
Parent send to 6623 pid
I (6623) receive: Zlb$,d"BGDJibmr@+op}("vm1CPq&qXyxU8&::G{wpeZyY5%c@#jB4rRW]^v
Parent send to 6623 pid
Parent send to 6623 pid
I (6623) receive: MWdS1tD2O)^mgLY2<^DUnz+;B)_3o=4=/3,?)OkqWJyZvT'M3d=#`GW#j85Z
Parent send to 6625 pid
I (6623) receive: 8>cj7;sb4?SjWIJ(Lb$on!pN-Acg>}Kp=/umcikw)Y|y=H#hE@rN@}7gZyiw
I (6623) receive: O$jwxr[|xmAS';oNWs.v"vR!.TZ)>lVlpAd%NZ=HI]zO3&8jx_{zVh6d=+(t
I (6623) receive: ]{#9zB"V^I:V^$h~Umw5j.km]j,gq;yi8{=3X>$7#=lzZpy0^._IUeR4P]6\
I (6624) receive: %b82j1Sll+2MlR57e3Erubv5Qo2dV<u[9H($Yto`~<.'*]=*o|{"_s6K}GJT
I (6624) receive: 8,IlCNB\0>o;$J5v_SZ~p_[%SIuK((zY3^aVG$MV[=,x#[p{Ie6T`qYN;ix\
I (6625) receive: 0`JG8]~ozQq9Xm.I#>)0|ke|>xM6/DIY%.!V&:F"jS:D[G(]~Jm77S4nfz@0
I (6624) receive: /7?lwt46]%pyKi7't3iuc?VU3?+{8f)G8HN0Wb_5"P0LU`ldsWZW1KGCiQ?=
I (6625) exited
I (6624) receive: b}j+L5aI0vKyA2O":O0,D"<oH^s48K"yI'?1U"Yd3?_SQInjw:u=;LG}+UL\
I (6624) receive: b2|u=<9'B+xl%S}rsKAXg]9I5V4L&m;h!8xWnL^1VW8tE6h9zD,b"E-66Z|;
I (6624) exited
I (6623) exited
Исходная версия vodz, :
Таки и пришлось за вас всё писать:
#include <limits.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
/* Обработчик сигнала SIGCHLD */
static int *childs;
static int n;
static void
my_handler (int nsig)
{
int i;
for(;;) {
int pid = waitpid (-1, NULL, nsig == 0 ? 0 : WNOHANG);
if(pid < 0)
continue;
if(pid == 0)
return;
for(i = 0; i < n; i++)
if(childs[i] == pid) {
childs[i] = 0;
return;
}
}
}
static int get_int(const char *prompt)
{
long r;
char *e;
char inbuf[128];
for(;;) {
printf ("%s ", prompt);
if(fgets (inbuf, sizeof (inbuf), stdin) == NULL)
exit(0);
errno = 0;
r = strtol(inbuf, &e, 10);
if(e == inbuf || errno != 0 || *e != '\n' || r <= 0 || r > INT_MAX) {
fprintf(stderr, "Strange number '%s'\n", inbuf);
} else {
return r;
}
}
}
#define MSG_LENGHT 60
static void fill_msg(char *buf)
{
int i;
for(i = 0; i < MSG_LENGHT; i++) {
buf[i] = '!' + (rand() % ('~' - ' '));
}
buf[i] = '\n';
}
int
main (void)
{
int fd, i, m;
pid_t pid;
ssize_t r;
char *file_name;
int *p_pipefd;
int *PIP1;
char inbuf[MSG_LENGHT + 2];
n = get_int ("Сколько дочерних процессов создать");
m = get_int ("Количество циклов * количество процессов");
p_pipefd = malloc (n * 3 * sizeof (int));
childs = p_pipefd + n * 2;
for (i = 0; i < n; i++) {
PIP1 = p_pipefd + i * 2;
pipe (PIP1);
fd = snprintf (NULL, 0, "Foo_%d.txt", i + 1);
file_name = alloca (fd + 1);
snprintf (file_name, fd + 1, "Foo_%d.txt", i + 1);
(void) signal (SIGCHLD, my_handler);
if ((pid = fork ()) != 0) {
//PARENT
if(pid < 0) {
fprintf(stderr, "fork(): %s\n", strerror(errno));
return 1;
}
close (PIP1[0]);
childs[i] = pid;
} else {
//CHILD
int my_pid = getpid();
close (PIP1[1]);
fd = open (file_name, O_WRONLY | O_CREAT, 0666);
if (fd == -1) {
fprintf (stderr, "File '%s' create failed!\n", file_name);
return 1;
}
while ((r = read (PIP1[0], inbuf, MSG_LENGHT + 1)) > 0) {
write (fd, inbuf, r);
printf ("I (%d) receive: %s", my_pid, inbuf);
}
printf ("I (%d) exited\n", my_pid);
return 0;
}
}
for (i = 0; i < (n * m); i++) {
fd = rand () % n;
fill_msg(inbuf);
printf("Parent send to %d pid\n", childs[fd]);
write (p_pipefd[fd * 2 + 1], inbuf, MSG_LENGHT + 1);
}
for (i = 0; i < n; i++)
close (p_pipefd[i * 2 + 1]);
my_handler(0);
return 0;
}
$ ./a.out
Сколько дочерних процессов создать 3
Количество циклов * количество процессов 4
Parent send to 6624 pid
Parent send to 6623 pid
Parent send to 6623 pid
Parent send to 6624 pid
Parent send to 6624 pid
Parent send to 6624 pid
I (6623) receive: A07$Q:vFEr_`!f%w>/$U+%59T`7z+kwe6/%gczHCm)>**C<aQY8uwf0LaFa(
Parent send to 6623 pid
Parent send to 6624 pid
Parent send to 6623 pid
I (6623) receive: Zlb$,d"BGDJibmr@+op}("vm1CPq&qXyxU8&::G{wpeZyY5%c@#jB4rRW]^v
Parent send to 6623 pid
Parent send to 6623 pid
I (6623) receive: MWdS1tD2O)^mgLY2<^DUnz+;B)_3o=4=/3,?)OkqWJyZvT'M3d=#`GW#j85Z
Parent send to 6625 pid
I (6623) receive: 8>cj7;sb4?SjWIJ(Lb$on!pN-Acg>}Kp=/umcikw)Y|y=H#hE@rN@}7gZyiw
I (6623) receive: O$jwxr[|xmAS';oNWs.v"vR!.TZ)>lVlpAd%NZ=HI]zO3&8jx_{zVh6d=+(t
I (6623) receive: ]{#9zB"V^I:V^$h~Umw5j.km]j,gq;yi8{=3X>$7#=lzZpy0^._IUeR4P]6\
I (6624) receive: %b82j1Sll+2MlR57e3Erubv5Qo2dV<u[9H($Yto`~<.'*]=*o|{"_s6K}GJT
I (6624) receive: 8,IlCNB\0>o;$J5v_SZ~p_[%SIuK((zY3^aVG$MV[=,x#[p{Ie6T`qYN;ix\
I (6625) receive: 0`JG8]~ozQq9Xm.I#>)0|ke|>xM6/DIY%.!V&:F"jS:D[G(]~Jm77S4nfz@0
I (6624) receive: /7?lwt46]%pyKi7't3iuc?VU3?+{8f)G8HN0Wb_5"P0LU`ldsWZW1KGCiQ?=
I (6625) exited
I (6624) receive: b}j+L5aI0vKyA2O":O0,D"<oH^s48K"yI'?1U"Yd3?_SQInjw:u=;LG}+UL\
I (6624) receive: b2|u=<9'B+xl%S}rsKAXg]9I5V4L&m;h!8xWnL^1VW8tE6h9zD,b"E-66Z|;
I (6624) exited
I (6623) exited