管道与FIFO

管道可用来相关进程间传递数据,FIFO是管道的变体,可用于任何进程间的通信。管道又被分为无名管道和有名管道

管道(无名管道)的创建,使用:

父子进程通信:

#include<stdio.h>
#include <string.h>
#include <sys/types.h>
 #include <unistd.h>
 
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>

#include "error_functions.h"

#define BUF_SIZE 30
int main (int argc,char **argv)
{
int fd[2];
char buf[10];
int numRead;
if(argc!=2||strcmp(argv[1],"--help")==0)
{
    usageErr("%s string\n", argv[0]);

}
if(pipe(fd))
{
errExit("pipe");
}
switch(fork())
{
case -1:
errExit("fork");

case 0:
    if(close(fd[1]==-1))
        {
        errExit("clsoe--child");
        }
    while(1)
        {
        
    numRead=read(fd[0],buf,BUF_SIZE);
    if(numRead==-1)
        errExit("read");
    if(numRead==0)
        break;
    if(write(STDOUT_FILENO,buf,numRead)!=numRead)
        {fatal("child-partail/faild write");}
    else
        {
        break;
        }
        }
    write(STDOUT_FILENO,"\n",1);
    if(close(fd[0])==-1)
        {
        errExit("close");
        }
    _exit(EXIT_SUCCESS);
default:
    
    if(close(fd[0])==-1)
        errExit("close");
        sleep(5);
    if(write(fd[1],argv[1],strlen(argv[1]))!=strlen(argv[1]))
        fatal("parent - partial/failed write");

    if(close(fd[1])==-1)
        errExit("close");
    wait(NULL);
    exit(EXIT_SUCCESS);
}    

}

用管道同步多个进程:

#include<stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include"curr_time.h"
 #include "get_num.h"
#include "error_functions.h"

int main(int argc,char **argv)
{
    int fd[2];
    int j=0,dump;
    if(argc<2||strcmp(argv[1],"--help")==0)
        usageErr("%s sleep-time ...\n",argv[0]);

    printf("%s Parent started \n",currTime("%T"));
    if(pipe(fd)==-1)
        errExit("pipe");
    for(j=1;j<argc;j++)
    {
        switch(fork())
        {
        case -1:
            errExit("fork");
            case 0:
                if(close(fd[0])==-1)
                    errExit("close");
                sleep(getInt(argv[j],1,"sleep-time"));
                //sleep(aoit(argv[j]));
                printf("%s child %d (pipe =%ld) closing pipe\n",currTime("%T"),j,(long)getpid());
                if(close(fd[1])==-1)
                    errExit("close");
                _exit(EXIT_SUCCESS);
        default:
            break;
            
        }
    }
    if(close(fd[1])==-1)
        errExit("close");
    if(read(fd[0],&dump,1)!=0)
        fatal("patrnt didn't get EOF\n");
    printf("%s parent read to go \n",currTime("%T"));
    exit(EXIT_SUCCESS);
}

FIFO(有名管道):

FIFO与管道类似,差别在于FIFO在文件系统中拥有一个名称,打开方式与普通文件一样。好出就是能够在非相关的进程间通信。

$ mkfifo [ -m mode] pathname

pathname是创建的FIFO名称,-m选项用来指定权限mode,与chmod 类似。

用FIFO实现简单迭代服务器:

客户端:

#include<stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include"curr_time.h"
#include "get_num.h"
#include "error_functions.h"

    


#define SEVRER_FIFO "/tmp/seqnum_sv"
#define CLIENT_FIFO_Template "/tmp/seqnum_cl.%ld"
#define CLIENT_FIFO_NAME_LEN (sizeof(CLIENT_FIFO_Template)+20)
static char clientfifo[CLIENT_FIFO_NAME_LEN];
struct request{
pid_t pid;
int seqlen;
};
struct response{
    int seqNum;
    };

int main(int argc,char **argv)
{
    int serverFd,clientFd;
    struct request req;
    struct response resp;
    if(argc >1 && strcmp(argv[1],"--help")==0)
        usageErr("%s [seq-len...]\n",argv[0]);
    umask(0);
    snprintf(clientfifo,CLIENT_FIFO_NAME_LEN,CLIENT_FIFO_Template,(long)getpid());

    if(mkfifo(clientfifo,S_IRUSR|S_IWUSR|S_IWGRP)==-1)
    {
    errExit("mkfifo");

    }
    req.pid=getpid();
    req.seqlen=(argc>1)?getInt(argv[1],GN_GT_0,"seq-len"):1;

    serverFd=open(SEVRER_FIFO,O_WRONLY);
    if(serverFd==-1)
        errExit("open");
    if(write(serverFd,&req,sizeof(struct request))!=sizeof(struct request))
        errExit("can not write serverFd");
    clientFd=open(clientfifo,O_RDONLY);
    if(clientFd==-1)
        errExit("can not open clientfifo");
    if(read(clientFd,&resp,sizeof(struct response))!=sizeof(struct response))
        fatal("can't read response from server");
    printf("%d\n",resp.seqNum);
    exit(EXIT_SUCCESS);


}
服务端:

#include<stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include"curr_time.h"
 #include "get_num.h"
#include "error_functions.h"
#define SEVRER_FIFO "/tmp/seqnum_sv"
#define CLIENT_FIFO_Template "/tmp/seqnum_cl.%ld"
#define CLIENT_FIFO_NAME_LEN (sizeof(CLIENT_FIFO_Template)+20)
struct request{
pid_t pid;
int seqlen;
};
struct response{
    int seqNum;
    };
int main(int argc,char **argv)
{
    int serverFd,clientFd,dummyFd;
    char clientFifo[CLIENT_FIFO_NAME_LEN];
    struct request req;
    struct response resp;
    int seqNum=0;
    umask(0);
    printf("123\n");
    if(mkfifo(SEVRER_FIFO,S_IRGRP|S_IWGRP|S_IWUSR)<0)
    {
    errExit("mkfifo %s",SEVRER_FIFO);
    }
        printf("12\n");
    serverFd=open(SEVRER_FIFO,O_RDONLY);
    if(serverFd<0)
    {
    errExit("open %s",SEVRER_FIFO);
    }
    dummyFd=open(SEVRER_FIFO,O_WRONLY);
    if(dummyFd<0)
    {
    errExit("open %s",SEVRER_FIFO);
    }
    //屏蔽信号SIGPIPE
    if(signal(SIGPIPE,SIG_IGN)==SIG_ERR)
        errExit("signal");
    for(;;)
    {
        if(read(serverFd,&req,sizeof(struct request))!=sizeof(struct request))
        {

        continue;
        }
        printf("server req.pid=%ld",(long)req.pid);
        snprintf(clientFifo,CLIENT_FIFO_NAME_LEN,CLIENT_FIFO_Template,(long)req.pid);
        //
        clientFd=open(clientFifo,O_WRONLY);
        if(clientFd<0)
            {
            errMsg("open %s",clientFifo);
            continue;
            }

        resp.seqNum=seqNum;
        if(write(clientFd,&resp,sizeof(struct response))!=sizeof(struct response))
        {
        fprintf(stderr,"Error writing to FIFO %s \n",clientFifo);
        }
        seqNum+=req.seqlen;
    }
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值