第一个例子:fork() 出子进程,父进程关闭pipe读,使用write 向管道写入,子进程关闭pipe写,然后从管道读取。
-
#include <apue.h>
-
-
#define READ_FD 0
-
#define WRITE_FD 1
-
-
int main(int argc, char *argv[])
-
{
-
int i;
-
int bytesread;
-
int fd[2];
-
char message[BUFSIZ];
-
-
// check proper usage
-
if(argc < 2){
-
fprintf(stderr, "Usage: %s message \n",argv[0]);
-
exit(1);
-
}
-
-
// try to create pipe
-
if( -1 == pipe(fd)){
-
perror("pipe call");
-
exit(2);
-
}
-
-
//create child process
-
switch(fork()){
-
case -1:
-
//fork failed
-
perror("fork failed");
-
exit(3);
-
-
case 0:
-
//child code
-
//close write end, otherwise child will never terminate
-
close(fd[WRITE_FD]);
-
//loop while not end of ile or not a read error
-
while((bytesread = read(fd[READ_FD],message, BUFSIZ))!= 0)
-
if(bytesread >0 ){ //more data
-
message[bytesread]='\0';
-
printf("Child received the word: '%s'\n",message);
-
fflush(stdout);
-
}
-
else{//read error
-
perror("read() ");
-
exit(4);
-
}
-
exit(0);
-
-
default: //parent code
-
close(fd[READ_FD]); //close read end,since parent is writing
-
for(i=1; i< argc; i++)
-
//send each word separately
-
if(write(fd[WRITE_FD],argv[i],strlen(argv[i]))!=-1)
-
{
-
printf("Parent sent the word: '%s' \n",argv[i]);
-
fflush(stdout);
-
}
-
else{
-
perror("write()");
-
exit(5);
-
}
-
close(fd[WRITE_FD]);
-
-
//wait for child so it does not remain a zombie
-
//do not care about it's status,so pass a NULL pointer
-
if( wait(NULL)==-1){
-
perror("Wait failed");
-
exit(2);
-
}
-
}
-
exit(0);
-
}
第二个例子:这个例子纯粹是为了说明write 写入的内容小于PIPE_BUF 的时候,操作是原子性的。
fork出两个进程,一个进程写入X,另外一个进程写入y,父进程向两个子进程发送SIGUSR1的信号,子进程开始写入,父进程读取管道内容,然后写入pd2_output。
-
#include <apue.h>
-
#include <sys/wait.h>
-
#include <unistd.h>
-
#include <limits.h>
-
#include <fcntl.h>
-
-
-
#define READ_FD 0
-
#define WRITE_FD 1
-
#define RD_CHUNK 10
-
#define ATOMIC
-
-
#ifndef PIPE_BUF
-
#define PIPE_BUF _POSIX_PIPE_BUF
-
#endif
-
-
void do_nothing(int signo)
-
{
-
return ;
-
}
-
-
int main(int argc, char *argv[])
-
{
-
int i,repeat;
-
int bytesread;
-
int mssglen;
-
pid_t child1, child2;
-
int fd[2];
-
int outfd;
-
-
char message[RD_CHUNK + 1];
-
char *Child1_Chunk, *Child2_Chunk;
-
long Chunk_Size;
-
-
static struct sigaction sigact;
-
-
sigact.sa_handler=do_nothing;
-
sigfillset(&(sigact.sa_mask));
-
sigaction(SIGUSR1, &sigact, NULL);
-
-
//check argc
-
if( argc < 2){
-
fprintf(stderr,"Usage: %s size \n",argv[0]);
-
exit(1);
-
}
-
-
//try to create pipe
-
if(-1 == pipe(fd)){
-
perror("pipe call");
-
exit(2);
-
}
-
-
repeat=atoi(argv[1]);
-
-
#ifdef ATOMIC
-
Chunk_Size = PIPE_BUF;
-
#else
-
Chunk_Size = PIPE_BUF + 200;
-
#endif
-
printf("Chunk size =%ld\n",Chunk_Size);
-
printf("Value of PIPE_BUF is %ld\n",PIPE_BUF);
-
Child1_Chunk=calloc(Chunk_Size,sizeof(char));
-
Child2_Chunk=calloc(Chunk_Size,sizeof(char));
-
if((NULL == Child1_Chunk) ||(NULL == Child2_Chunk)){
-
perror("calloc");
-
exit(2);
-
}
-
-
//create the string that child1 writes
-
Child1_Chunk[0] = '\0'; //just to be safe
-
for(i=0; i < Chunk_Size -2; i++)
-
strcat(Child1_Chunk,"X");
-
strcat(Child1_Chunk,"\n");
-
-
//create the string that child2 writes
-
Child2_Chunk[0]='\0'; //just to be safe
-
for(i=0;i<Chunk_Size -2;i++)
-
strcat(Child2_Chunk,"y");
-
strcat(Child2_Chunk,"\n");
-
-
//create first child process
-
switch(child1 = fork()){
-
case -1: //fork failed -- exit
-
perror("fork()");
-
exit(3);
-
-
case 0: //child1 code
-
mssglen=strlen(Child1_Chunk);
-
pause();
-
//sleep(5);
-
for(i=0;i<repeat;i++){
-
if(write(fd[WRITE_FD],Child1_Chunk,mssglen)!= mssglen){
-
perror("write");
-
exit(4);
-
}
-
}
-
close(fd[WRITE_FD]);
-
exit(0);
-
-
default: //parent creates second child process
-
switch(child2 = fork()){
-
case -1: //fork failed --exit
-
perror("fork()");
-
exit(5);
-
-
case 0: //child2 code
-
mssglen=strlen(Child2_Chunk);
-
pause();
-
for(i=0;i<repeat;i++){
-
if(write(fd[WRITE_FD],Child2_Chunk,mssglen)!= mssglen){
-
perror("write");
-
exit(6);
-
}
-
}
-
close(fd[WRITE_FD]);
-
exit(0);
-
-
default: //parent code
-
outfd=open("pd2_output",O_WRONLY|O_CREAT|O_TRUNC,0644);
-
if(-1==outfd){
-
perror("open");
-
exit(7);
-
}
-
close(fd[WRITE_FD]);
-
kill(child2,SIGUSR1);
-
kill(child1,SIGUSR1);
-
while((bytesread = read(fd[READ_FD],message,RD_CHUNK))!=0)
-
if(bytesread >0 ){ //more data
-
write(outfd,message,bytesread);
-
}
-
else{
-
perror("read() ");
-
exit(8);
-
}
-
close(outfd);
-
//collect zombies
-
for(i=1;i<=2;i++)
-
if(wait(NULL)==-1){
-
perror("wait failed");
-
exit(9);
-
}
-
close(fd[READ_FD]);
-
free(Child1_Chunk);
-
free(Child2_Chunk);
-
}
-
exit(0);
-
}
-
}
3. 最后一个例子:管道的最大容量居然是65536,如果管道内空间少于4096,则不能写入。
-
#include <apue.h>
-
#include <limits.h>
-
#include <unistd.h>
-
-
int count = 0;
-
sig_atomic_t full =0;
-
-
/* The SIGALRM handler, this sets the full flag to indicate that the
-
write call blocked, and it prints the number of characters written
-
to the pipe so far */
-
-
void on_alarm(int signo)
-
{
-
printf("\n Write() blocked with %d chars in the pipe.\n",count);
-
full=1;
-
}
-
-
-
int main(int argc, char *argv[])
-
{
-
int fd[2];
-
int pipe_size;
-
int bytesread;
-
int amount_to_remove;
-
-
char buffer[PIPE_BUF];
-
char c='x';
-
static struct sigaction sigact;
-
-
sigact.sa_handler=on_alarm;
-
sigfillset(&(sigact.sa_mask));
-
sigaction(SIGALRM,&sigact,NULL);
-
-
if( -1 == pipe(fd)){
-
perror("pipe failed");
-
exit(1);
-
}
-
-
/* Check whether the _PC_PIPE_BUF constant returns the pipe capacity
-
or the atomic write size */
-
pipe_size = fpathconf(fd[0],_PC_PIPE_BUF);
-
-
while (1){
-
/* set an alarm long enough that if write fails it will fail
-
within this amount of time. 8 seconds is long enough */
-
alarm(4);
-
write(fd[1],&c,1);
-
//unset the alarm
-
alarm(0);
-
-
//Did alarm expire? if so, write failed and we stop the loop
-
if(full)
-
break;
-
-
//report how many chars written so far
-
if(( ++count %1024)==0)
-
printf("%d chars in pipe \n",count);
-
}
-
-
printf("The maximum number of bytes that the pipe stored is %d.\n",count);
-
printf("The value returned by fpathconf (fd,_PC_PIPE_BUF) is %d.\n\n",pipe_size);
-
-
printf("Now we remove characters from the pipe and demonstrate that "
-
"we can not \n"
-
"write into the pipe unless it has %d (PIPE_BUF) free bytes.\n",PIPE_BUF);
-
-
amount_to_remove= PIPE_BUF -1;
-
-
printf("First we remove %d characters (PIPE_BUF -1) and try to write into the pipe.\n",amount_to_remove);
-
full=0;
-
bytesread=read(fd[0],&buffer,amount_to_remove);
-
if(bytesread < 0){
-
perror("error reading pipe");
-
exit(1);
-
}
-
-
count = count - bytesread;
-
alarm(4);
-
write(fd[1],&c, 1);
-
//unset the alarm
-
alarm(0);
-
if(full)
-
printf("We could not write into the pipe.\n");
-
else
-
printf("We successfully wrote into the pipe.\n");
-
-
amount_to_remove =PIPE_BUF - amount_to_remove;
-
full=0;
-
-
printf("\n Now we remove one more character and try to write into the pipe.\n");
-
-
bytesread=read(fd[0],&buffer, amount_to_remove);
-
if(bytesread < 0){
-
perror("error reading pipe");
-
exit(1);
-
}
-
-
count = count - bytesread;
-
alarm(4);
-
-
write(fd[1],&c, 1);
-
//unset the alarm
-
alarm(0);
-
if(full)
-
printf("We could not write into the pipe.\n");
-
else
-
printf("We successfully wrote into the pipe.\n");
-
-
return 0;
-
}
阅读(3456) | 评论(0) | 转发(0) |