首页 > 系统相关 >进程间通信-信号-pipe-fifo

进程间通信-信号-pipe-fifo

时间:2022-11-13 18:33:27浏览次数:37  
标签:pipe int res fifo 间通信 fd printf include

  任务详情

编译运行附件中的代码,提交运行结果截图
理解代码,特别是相关系统调用的使用。

Linux进程间通信

进程是程序运行资源分配的最小单位。每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,Inter-Process Communication)。

运行云班课中的老师所给的代码pipedemo.c

代码如下:

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <unistd.h>

int main()
{
    int    len, i, apipe[2];//两个文件描述符    
    char    buf[BUFSIZ];//长度为BUFSIZ        
    
    if ( pipe ( apipe ) == -1 ){
        perror("could not make pipe");
        exit(1);
    }
    printf("Got a pipe! It is file descriptors: { %d %d }\n", 
                            apipe[0], apipe[1]);


    while ( fgets(buf, BUFSIZ, stdin) ){//从输入端获取字符,存入buf数组中
        len = strlen( buf );
        if (  write( apipe[1], buf, len) != len ){//apipe[1]是写入端,这里write()函数将buf指针指向的内存的len长个字节写入到apipe[1]所指向的管道缓冲区中。
            perror("writing to pipe");        
            break;                    
        }
        for ( i = 0 ; i<len ; i++ )                     
            buf[i] = 'X' ;
        len = read( apipe[0], buf, BUFSIZ ) ;        
        if ( len == -1 ){                
            perror("reading from pipe");        
            break;
        }
        if ( write( 1, buf,len ) != len ){        
            perror("writing to stdout");        
            break;                    
        }
    }
}

运行结果如图:

 

 运行云班课中老师所给的代码pipedemo2.c

运行结果如图:

 

 

命名管道fifo

fifo简介

FIFO(First In First Out)文件在磁盘上没有数据块,仅仅是内核中一条通道,各进程可以读写从而实现的进程间通信。支持多端读或多端写;

严格遵循先进先出原则;

不支持诸如seek()等文件定位操作;

 

 

命名管道fifo

先运行编译testmf.c文件,代码如下:

#include  <stdio.h>
#include  <stdlib.h>
#include  <sys/types.h>
#include  <sys/stat.h>

int main()
{
    int res = mkfifo("/tmp/myfifo", 0777);
    if (res == 0) {
        printf("FIFO created \n");
    }
    exit(EXIT_SUCCESS);
}

编译运行consumer.c和producer.c,

consumer.c代码如下:

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

#define FIFO_NAME "/tmp/myfifo"
#define BUFFER_SIZE PIPE_BUF


int main()
{
    int pipe_fd;
    int res;

    int open_mode = O_RDONLY;
    char buffer[BUFFER_SIZE + 1];
    int bytes = 0;

    memset(buffer, 0, sizeof(buffer));

    printf("Process %d opeining FIFO O_RDONLY \n", getpid());
    pipe_fd = open(FIFO_NAME, open_mode);
    printf("Process %d result %d\n", getpid(), pipe_fd);

    if (pipe_fd != -1) {
        do {
            res = read(pipe_fd, buffer, BUFFER_SIZE);
            bytes += res;
        } while (res > 0);
        close(pipe_fd);
    } else {
        exit(EXIT_FAILURE);
    }

    printf("Process %d finished, %d bytes read\n", getpid(), bytes);
    exit(EXIT_SUCCESS);
}

producer.c代码如下:

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

#define FIFO_NAME "/tmp/myfifo"
#define BUFFER_SIZE PIPE_BUF
#define TEN_MEG (1024 * 1024 * 10)

int main()
{
    int pipe_fd;
    int res;
    int open_mode = O_WRONLY;

    int bytes = 0;
    char buffer[BUFFER_SIZE + 1];

    if (access(FIFO_NAME, F_OK) == -1) {
        res = mkfifo(FIFO_NAME, 0777);
        if (res != 0) {
            fprintf(stderr, "Could not create fifo %s \n",
                FIFO_NAME);
            exit(EXIT_FAILURE);
        }
    }

    printf("Process %d opening FIFO O_WRONLY\n", getpid());
    pipe_fd = open(FIFO_NAME, open_mode);
    printf("Process %d result %d\n", getpid(), pipe_fd);

    if (pipe_fd != -1) {
        while (bytes < TEN_MEG) {
            res = write(pipe_fd, buffer, BUFFER_SIZE);
            if (res == -1) {
                fprintf(stderr, "Write error on pipe\n");
                exit(EXIT_FAILURE);
            }
            bytes += res;
        }
        close(pipe_fd);
    } else {
        exit(EXIT_FAILURE);
    }

    printf("Process %d finish\n", getpid());
    exit(EXIT_SUCCESS);
} 

signal信号

运行云班课中所给代码sigdemo1.c:

代码如下:

#include    <stdio.h>
#include    <signal.h>
void    f(int);            
int main()
{
    int    i;
    signal( SIGINT, f );        
    for(i=0; i<5; i++ ){        
        printf("hello\n");
        sleep(2);
    }

    return 0;
}

void f(int signum)            
{
    printf("OUCH!\n");
}

运行结果如图:

 

 运行云班课中所给代码sigdemo2.c:

代码如下:

#include    <stdio.h>
#include    <signal.h>

main()
{
    signal( SIGINT, SIG_IGN );//SIG_IGN为默认信号忽略

    printf("you can't stop me!\n");
    while( 1 )
    {
        sleep(1);
        printf("haha\n");
    }
}

运行结果如图:

 

 运行云班课中所给代码sigactdemo.c:

代码如下:

#include    <stdio.h>
#include        <unistd.h>
#include    <signal.h>
#define    INPUTLEN  100
void inthandler();    
int main()
{
    struct sigaction newhandler;//定义一个sigaction结构体newhandler    
    sigset_t blocked;    
    char x[INPUTLEN];
    newhandler.sa_handler = inthandler;//处理中断时调用inthandler()函数。    
    newhandler.sa_flags = SA_RESTART|SA_NODEFER
        |SA_RESETHAND;    //被阻断时**重新输入**且允许递归调用处理函数,但当处理函数被调用时需要重置才再次有效
    sigemptyset(&blocked);    
    sigaddset(&blocked, SIGQUIT);    
    newhandler.sa_mask = blocked;    
    if (sigaction(SIGINT, &newhandler, NULL) == -1)
        perror("sigaction");
    else
        while (1) {
            fgets(x, INPUTLEN, stdin);
            printf("input: %s", x);
        }
    return 0;
}
void inthandler(int s)//中断处理时调用的函数
{
    printf("Called with signal %d\n", s);//输出这个操作代表的的信号量
    sleep(s * 4);
    printf("done handling signal %d\n", s);
}

运行结果如图:

 

 运行云班课所给代码sigactdemo2.c:

代码如下:

#include <unistd.h>
#include <signal.h>
#include <stdio.h>

void sig_alrm( int signo )
{
    /*do nothing*/
}

unsigned int mysleep(unsigned int nsecs)
{
    struct sigaction newact, oldact;
    unsigned int unslept;

    newact.sa_handler = sig_alrm;  //在内核注册SIGALRM信号的处理函数sig_alrm
    sigemptyset( &newact.sa_mask );//初始化sa_mask所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号。
    newact.sa_flags = 0; //当某个信号的处理函数被调用时候,当前的信号被加入到进程的信号阻塞集,如果想让其他信号也加入到信号阻塞集合就通过sa_mask来说明。
    sigaction( SIGALRM, &newact, &oldact );//这里被替换的结构体是oldact,原来的结构体是newact 
 //通过传入newact修改了SIGALRM信号的处理动作,传入oldact读取SIGALRM原来的处理动作
 //把SIGALRM对应的编号传入信号处理注册函数(sig_alrm)的参数列表中。
    alarm( nsecs ); //在当前进程设定闹钟,时间一到就终止当前进程
    pause();//将进程挂起,直到有信号抵达
    unslept = alarm ( 0 );
    sigaction( SIGALRM, &oldact, NULL );

    return unslept;
}

int main( void )
{
    while( 1 )
    {
        mysleep( 2 );
        printf( "Two seconds passed\n" );
    }

    return 0;
}

运行结果如图:

 

标签:pipe,int,res,fifo,间通信,fd,printf,include
From: https://www.cnblogs.com/syf0105/p/16875821.html

相关文章

  • 进程间通信-信号-pipe-fifo
    进程间通信-信号-pipe-fifo一、fifo1testmf.c——创建一个fifo2producer/consumer生产者和消费者二、pipe1pipe.c获取参数,执行命令2pipedemo.c获取键盘输......
  • 进程间通信-信号-pipe-fifo
    一、有名管道(FIFO)相关概念FIFO(Firstin,Firstout)为一种特殊的文件类型,它在文件系统中有对应的路径。当一个进程以读的方式打开该文件,而另一个进程以写的方式打开该......
  • 进程间通信-信号-pipe-fifo
    fifo管道在有名管道(namedpipe或FIFO)提出后,管道(pipe)限制得到了克服。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FI......
  • 20201317 LYX Linux进程间通信学习
    Linux进程间通信1、匿名管道:pipe2、命名管道:fifo3、内存映射:mmap4、信号进程是程序运行资源分配的最小单位。每个进程各自有不同的用户地址空间,任何一个进程的全局变......
  • 流式数据库PipelineDB之BF杂谈
    流式数据库PipelineDB1.导语PipelineDB是一个PostgreSQL的一个流式数据库,是pg社区的一个扩展。下面来引入PipelineDB里面的一些概念:1.1什么是流?流是一种允许客户端将时序......
  • 进程间通信的方式
    进程通信的介绍进程间通信(ProcessToProcessCommunication)是指在并行计算过程中,各进程之间进行数据交互或消息传递,其通信量的大小主要取决于并行设计的粒度划分和各个......
  • 进程间通信-信号-pipe-fifo
    编译运行附件中的代码,提交运行结果截图理解代码,特别是相关系统调用的使用。一、有名管道FIFOFIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文......
  • 进程间通信-信号-pipe-fifo
    1.PIPE1.pipe.c:调用参数所对应的命令2.pipedemo.c:创建一个pipe并读/写3.pipedemo2.c4.stdinredir1.c:打印root权限5.stdinredir2.c6.testtty.c7.whotofile.c......
  • 进程间通信-信号-pipe-fifo
    一、有名管道FIFO(一)知识点1.在有名管道(namedpipe或FIFO)提出后,管道(pipe)限制得到了克服。值得注意的是,FIFO严格遵循先进先出(firstinfirstout),对管道及FIFO的读总是从......
  • 【转】BigPipe学习研究
    1.技术背景FaceBook页面加载技术试想这样一个场景,一个经常访问的网站,每次打开它的页面都要要花费6秒;同时另外一个网站提供了相似的服务,但响应时间只需3秒,那么你会如何选......