进程-IPC 管道 (一)

C++的创建命名管道(CreateNamedPipe) 一、命名管道(Named Pipes) 管道(Pipe)实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。 匿名管道(Anonymous Pipes)是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。 命名管道,顾名思义,这个管道肯定是有名字的。通过管道的名字来确保多个进程访问同一个管道。事实上,命名管道不仅可在同一台计算机的不同进程 阅读详情

详见:https://github.com/ZhangzheBJUT/linux/blob/master/IPC(%E4%B8%80).md

一 IPC 概述

进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。系统空间是“公共场所”,所以内核显然可以提供这样的条件,如下图所示。除此以外,那就是双方都可以访问的外设了,两个进程可以通过磁盘上的普通文件交换信息,或者通过“注册表”或其它数据库中的某些表项和记录交换信息。
                                              

linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)。它们在进程间通信方面的侧重点有所不同,前者对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了 system V IPC,通信进程局限在单个计算机内;后者则跳过了该限制,形成了基于套接字 socket的进程间通信机制。

Linux 则把两者继承了下来,如下图示:
                     

Unix  IPC包括: 管道、FIFO、信号;                                                                                
System V IPC包括:System V消息队列、System V信号灯、System V共享内存区;                                            
Posix IPC包括: Posix消息队列、Posix信号灯、Posix共享内存区。                                                       

有两点需要简单说明一下:                                                                                          
    1.由于Unix版本的多样性,电子电气工程协会(IEEE)开发了一个独立的Unix标准,这个新的ANSI Unix标准被称为计算
      机环境的可移植性操作系统界面(PSOIX)。现有大部分Unix和流行版本都是遵循POSIX标准的,而Linux从一开始就遵循POSIX标准;     
    2.BSD并不是没有涉足单机内的进程间通信(socket本身就可以用于单机内的进程间通信)。事实上,很多Unix版本的单
      机IPC留有BSD的痕迹,如4.4BSD支持的匿名内存映射、4.3+BSD对可靠信号语义的实现等等。

上图给出了linux 所支持的各种IPC手段,为了避免概念上的混淆,在尽可能少提及Unix的各个版本的情况下,所有问题的讨论最终都会归结到linux环境下的进程间通信上来。并且,对于linux所支持通信手段的不同实现版本(如对于共享内存来说,有Posix共享内存区以及System V共享内存区两个实现版本)下面将主要介绍Posix API。

linux下进程间通信的几种主要手段:

  • 管道(Pipe)及命名管道(named pipe):管道可用于具有亲缘关系进程间的通信;命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
  • 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux 除了支持Unix早期信号语义函数signal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数);
  • 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
  • 共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式,是针对其它通信机制运行效率较低而设计的。它往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
  • 消息队列:消息队列是消息的链接表,包括Posix消息队列和system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  • 套接字(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上,Linux和System V的变种都支持套接字。

二 管道

当从一个进程连接数据流到另一个进程时,使用术语管道(pipe)。通常是把一个进程的输出通过管道连接到另一个进程的输入。
对于shell命令来说,命令的连接是通过管道操作符来完成的,如下所示:

  cmd1 | cmd2    

  shell负责安排两个命令的标准输入和标准输出
  cmd1的标准输入来自终端键盘  
  cmd1的标准输出传递给cmd2,作为它的标准输入  
  cmd2的标准输出连接到终端屏幕

               
shell所做的工作实际上是对标准输入和标准输出流进行重新连接,使数据流从键盘输入通过两个命令最终输出到屏幕上。

2.1.poen与pclose函数

函数原型:

#include <stdio.h>  
FILE *popen(const char*command,const char *open_mode);  
int pclose(FILE *stream_to_close);

函数描述:

popen      函数允许一个程序将另一个程序作为新进程来启动,并可以传递数据给它或者通过它来接收数据。
command    字符串是要运行的程序名和相应的参数,这个命令被送到 /bin/sh 以 -c 参数执行, 即由 shell来执行。
open_mode  必须为"r"或者"w",二者只能选择一个,函数的返回值FILE*文件流指针,通过常用的stdio库函数
           (如fread)来读取被调用程序的输出。如果open_mode是"w",调用程序就可以用fwrite调用向被调用程序发送
           数据,而被调用程序可以在自己的标准输入上读取数据。

补:/bin/sh -c   
        Read commands from the command_string operand instead of from the standard input. 
        Special  parameter 0 will be  set from the command_name operand and the positional 
        parameters ($1, $2, etc.) set from the remaining argument operands.

读取外部程序的输出:

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

    int main()
    {
        FILE *read_fp;
        char buffer[BUFSIZ+1];
        int chars_read;

        memset(buffer,'\0',sizeof(buffer));
        read_fp = popen("uname -a","r");
        if (read_fp !=NULL)
        {
            chars_read = fread(buffer,sizeof(char),BUFSIZ,read_fp);
            if (chars_read>0)
            {
                printf("output was:-\n%s\n",buffer);
            }

            pclose(read_fp);
            exit(EXIT_SUCCESS);
        }
        exit(EXIT_FAILURE);
    }

将输出发送到外部程序:

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

    int main()
    {
        FILE *write_fp;
        char buffer[BUFSIZ+1];

        sprintf(buffer,"Once upon a time ,thera was ...\n");
        write_fp = popen("od -c","w");

        if (write_fp != NULL)   
        {
            fwrite(buffer,sizeof(char),strlen(buffer),write_fp);
            pclose(write_fp);
            exit(EXIT_SUCCESS);
        }
        exit(EXIT_FAILURE);
    }

注意:popen()函数的返回值是一个普通的标准I/O流,且它只能用pclose()函数来关闭,而不是fclose()。

popen函数运行一个程序时,它首先启动shell,即系统中的sh命令,然后将command字符串作为一个参数传递给它,由shell来负责分析命令字符串,它允许我们通过popen启动非常复杂的shell命令。使用shell的一个不太好的影响是,针对每个popen的调用,不仅要启动一个被请求的程序,还要启动一个shell,即每个popen调用将多启动两个进程,从节省资源的角度来看,popen函数的调用成本略高,而且对目标命令的调用比正常方式要慢一些。 pclose调用只在popen启动的进程结束后才返回。如果调用pclose时它仍在运行,pclose调用将等待该进程的结束。

2.2.pipe函数

底层pipe函数,通过这个函数在两个程序之间传递数据不需要启动一个shell来解释请求命令,它同时还提供了对读写数据的更多控制。

函数原型:

    #include <unistd.h>  
    int pipe(int file_descriptor[2]);

函数描述:

pipe 函数参数是一个由两个整数类型的文件描述符组成的数组的指针。该函数在数组中填上两个新的文件描述符后返回0,如果
失败则返回-1,并设置error来表明失败的原因。  
 常见的错误:
      EMFILE:进程使用的文件描述符过多
      ENFILE:系统的文件表已满
      EFAULT:文件描述符无效
两个返回的文件描述符以一种特殊的方式连接起来,写到file_descriptor[1]的所有数据都可以从file_descriptor[0]读出来。
数据基于先进先出的原则进行处理,意味着如果你把1,2,3写到file_descriptor[1],从file_descriptior[0]读取到的数据也
是1,2,3。

注意:调用pipe函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读端一个写端,然后通过file_descriptor 参数传出给用户程序两个文件描述符,file_descriptor[0]指向管道的读端,file_descriptor[1]指向管道的写端。在用户程序看起来管道就像一个打开的文件,通过read(file_descriptor[0])或者write(file_descriptor[1])来向这个文件读写数据,其实是在读写内核缓冲区。两个文件描述符被强制规定file_descriptor[0] 只能指向管道的读端,如果进行写操作就会出现错误;同理 file_descriptor[1]只能指向管道的写端,如果进行读操作就会出现错误。pipe使用的是文件描述符而不是文件流,所以必须使用底层的read和write调用来访问数据,而不是用文件流函数fread和fwrite。

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

    int main()
    {
        int data_processed;
        int file_pipes[2];
        const char some_data[] = "1233";
        char buffer[BUFSIZ+1];

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

        if (pipe(file_pipes)==0)
        {
            data_processed = write(file_pipes[1],some_data,strlen(some_data));
            printf("Wrote %d bytes \n",data_processed);

            data_processed = read(file_pipes[0],buffer,BUFSIZ);
            printf("Read %d bytes \n",data_processed);
            exit(EXIT_SUCCESS);
        }
        exit(EXIT_FAILURE);
    }

程序说明: 这个程序用数组 file_pipes 中的两个文描述符创建一个管道,然后它用文件描述符 file_pipes[1] 向管道中写数据 ,再从 file_pipes[0] 读回数据。

管道的真正优势体现在:两个进程之间传递数据。 当程序用fork调用创建新进程时,原先打开的文件描述符仍将保持打开状态。如果在原先的进程中创建一个管道,然后再调用fork创建新进程,即可以通过管道在两个进程之间传递数据,如下图所示:

         

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


int main()
{
    int data_processed;
    int file_pipes[2];

    const char some_data[] = "1233";
    char buffer[BUFSIZ+1];
    pid_t fork_result;


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

    if (pipe(file_pipes)==0)
    {
        fork_result  = fork();

        if (fork_result ==-1)
        {
            fprintf(stderr,"Fork failed");
            exit(EXIT_FAILURE);
        }

        if (fork_result ==0)
        {
            close(file_pipes[1]);
            sleep(2);
            data_processed = read(file_pipes[0],buffer,BUFSIZ);
            printf("Read %d bytes :%s \n",data_processed,buffer);


        }
        else
        {
            close(file_pipes[0]);
            data_processed = write(file_pipes[1],some_data,strlen(some_data));
            printf("Wrote %d bytes \n",data_processed);
        }

        exit(EXIT_SUCCESS);
    }
    exit(EXIT_FAILURE);
}

程序说明: 程序首先用pipe函数创建一个管道,接着用fork调用创建一个新进程。如果fork调用成功,父进程首先关闭读操作符,然后写数据到管道中,而子进程首先关闭写操作符,然后从管道中读取数据。父子进程都在只调用了一次write或read之后就退出。其原理如下图所示:
    

系统维护一个文件的文件描述符表计数,父子进程都各自有指向相同文件的文件描述符,当关闭一个文件描述符时,相应计数减1,当这个计数减到0时,文件就被关闭,因此虽然父进程关闭了其文件描述符 file_pipes[0],但是这个文件的文件描述符计数还没等于0,所以子进程还可以读取。也可以这么理解,父进程和子进程都有各自的文件描述符,虽然在父进程中关闭了file_pipes[0],但是对子进程中的 file_pipes[0] 没有影响。

注:1.文件表中的每一项都会维护一个引用计数,标识该表项被多少个文件描述符(fd)引用,在引用计数为0的时候,表项才会被删除。所以调用close(fd)关闭子进程的文件描述符,只会减少引用计数,但是不会使文件表项被清除,所以父进程依旧可以访问。
2.当没有数据可读时,read调用通常会阻塞,即它将暂停进程来等待直到有数据到达为止。如果管道的另一端已被关闭,也就是说没有进程打开这个管道并向它写数据了,此时read调用将会被阻塞。注意,这与读取一个无效的文件描述符不同,read把无效的文件描述符看做一个错误并返回-1.

在pipe使用中,也可以在子进程中运行一个与其父进程完全不同的另一个程序,而不是仅仅运行一个相同的程序。这个可由exec调用来实现。在上面的例子中,因为子进程本身有 file_pipes 数据的一个副本,所以这并不成为问题。但经过exec调用后,原来的进程已经被新的子进程替换了。为解决这个问题,可以将文件描述符(实际上是一个数字)作为一个参数传递给exec启动程序。详细实现见:pipe3.c 和 pipe4.c

2.3.命名管道FIFO

无名管道只能用在父子进程之间,这些程序由一个共同的祖先进程启动。但如果想在不同进程之间交换数据,这就不太方便。而这可以使用FIFO文件来完成在不相关的进程之间交换数据,它通常叫做命名管道(named pipe)。
命名管道是一种特殊类型的文件,它在文件系统中以文件名的形式存在,但它的行为却和已经看到过的没有名字的管道类似。

使用下面两个函数可以创建一个FIFO文件:

int mkfifo(const char*filename,mode_t mode)
int mknod(const char* filename,mode_t mode | S_IFIFO,(dev_t)0);

命名管道的一个非常有用特点是:由于它们出现在文件系统中,所以它们可以像平常的文件名一样在命令中使用,使用FIFO只是为了单向传递数据。

使用方法如下:

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

int main()
{
    int res = mk  fifo("/tmp/my_fifo",0777);
    if (res == 0)
    {
        printf("FIFO created.\n");
    }
    exit(EXIT_SUCCESS);
}

查看运行结果: 
注:输出结果中的第一个字符为p,表示这是一个管道文件。不同的用户掩码最后得到的文件访问权限是不同的(我的用户掩码为0002)。

与通过pipe调用创建管道不同,FIFO是以命名文件的形式存在,而不是打开的文件描述符,所以对它进行读写操作必须先打开它。FIFO也用open和close函数打开和关闭。 对FIFO文件来说,传递给open调用的是FIFO的路径名,而不是一个正常的文件。

打开一个FIFO文件的方法如下:

open(const char*path,O_RDONLY);
    在这种情况下,open调用将阻塞,除非有一个进程以写的方式打开同一个FIFO,否则它不会返回。
open(const char* path,O_RDONLY|O_NONBLOCK)
    在这种情况下,即使没有其它进程以写方式打开FIFO,open调用也将成功并立刻返回。
open(const char *path,O_WRONLY)
    在这种情况下,open调用将会阻塞,直到有一个进程以读方式打开一个FIFO为止。
open(const char*path,O_WRONLY|O_NONBLOCK)
    这个函数调用总是立刻返回,但如果没有一个进程以读方式打开FIFO文件,open调用将返回一个错误并且FIFO也不会被打开。
    如果确实有一个进程以读方式打开FIFO文件,那么我们就可以通过它返回的文件描述符对这个FIFO文件进行读写操作。

注意:

  • 使用open打开FIFO文件程序不能以O_RDWR模式打开FIFO文件进行读写操作。这样做的后果是未明确定义。如果确实需要在程序之间双向传递数据,最好使用一对FIFO。
  • O_NONBLOCK 分别搭配O_RDONLY 和 O_WRONLY在效果上是不同的,如果没有进程以读方式打开管道,非阻塞写方式的open调用将失败,但非阻塞读方式的open调用总是成功。close调用的行为并不受 O_NONBLOCK标志的影响。

    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    #define FIFO_NAME  "/tmp/my_fifo"
    
    int main(int argc,char* argv[])
    {
        int res;
        int open_mode = 0;
        int i;
    
        if (argc <2)
        {
            fprintf(stderr, "Usage:%s <some combination of \
                O_RDONLY O_WRONLY O_NONBLOCK>\n",*argv );
            exit(EXIT_FAILURE);
        }
    
        for (i = 1; i < argc; ++i)
        {   
            if (strncmp(*++argv,"O_RDONLY",8) == 0)
            {   
                open_mode |= O_RDONLY;
            }
            if (strncmp(*argv,"O_WRONLY",8) == 0    )
            {
                open_mode |= O_WRONLY;
            }
            if (strncmp(*argv,"O_NONBLOCK",10) == 0)
            {
                open_mode |= O_NONBLOCK;
            }
        }
    
        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\n",getpid());
        res = open(FIFO_NAME,open_mode);
        printf("Process %d result %d\n",getpid(),res);
        sleep(5);
        if (res != -1)
        {
            (void)close(res);
        }
        printf("Process %d finished\n",getpid());
        exit(EXIT_SUCCESS);
    }
    

使用 O_NONBLOCK模式会影响到对FIFO的read和write调用。

小结:
1. 从FIFO中读取数据

  • 如果有进程写打开FIFO,且当前FIFO为空,则对于设置了阻塞标志的读操作来说,将一直阻塞下去,直到有数据可以读时才继续执行;对于没有设置阻塞标志的读操作来说,则返回0个字节,当前errno值为EAGAIN,提示以后再试。
  • 对于设置了阻塞标志的读操作来说,造成阻塞的原因有两种:
    1、当前FIFO内有数据,但有其它进程在读这些数据;
    2、FIFO本身为空。
    解阻塞的原因是:FIFO中有新的数据写入,不论写入数据量的大小,也不论读操作请求多少数据量,只要有数据写入即可。
  • 读打开的阻塞标志只对本进程第一个读操作施加作用,如果本进程中有多个读操作序列,则在第一个读操作被唤醒并完成读操作后,其它将要执行的读操作将不再阻塞,即使在执行读操作时,FIFO中没有数据也一样(此时,读操作返回0)。
  • 如果没有进程写打开FIFO,则设置了阻塞标志的读操作会阻塞。
  • 如果FIFO中有数据,则设置了阻塞标志的读操作不会因为FIFO中的字节数少于请求的字节数而阻塞,此时,读操作会返回FIFO中现有的数据量。

2. 从FIFO中写入数据
FIFO的长度是需要考虑的一个很重要因素。
系统对任一时刻在一个FIFO中可以存在的数据长度是有限制的。它由#define PIPE_BUF定义,在头文件limits.h 中。在Linux和其它类UNIX系统中,它的值通常是4096字节,Red Hat Fedora9 下是4096,但在某些系统中它可能会小到512字节。
虽然对于只有一个FIFO写进程和一个FIFO读进程而言,这个限制并不重要,但只使用一个FIFO并允许多个不同进程向一个FIFO读进程发送写请求的情况是很常见的。如果几个不同的程序尝试同时向FIFO写数据,能否保证来自不同程序的数据块不相互交错就非常关键了。也就是说,必须保证每个写操作“原子化”。

  • 对于设置了阻塞标志的写操作:

    • 当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。如果此时管道空闲缓冲区不足以容纳要写入的字节数,则进入睡眠,直到当缓冲区中能够容纳要写入的字节数时,才开始进行一次性写操作。即写入的数据长度小于等于PIPE_BUF时,那么或者写入全部字节,或者一个字节都不写入,它属于一个一次性行为,具体要看FIFO中是否有足够的缓冲区。
    • 当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。FIFO缓冲区一有空闲区域,写进程就会试图向管道写入数据,写操作在写完所有请求的数据后返回。
  • 对于没有设置阻塞标志的写操作:

    • 当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。如果当前FIFO空闲缓冲区能够容纳请求写入的字节数,写完后成功返回;如果当前FIFO空闲缓冲区不能够容纳请求写入的字节数,则返回EAGAIN错误,提示以后再写。
    • 当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。在写满所有FIFO空闲缓冲区后,写操作返回。

  • 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
嵌入式STM32控制电梯面板 嵌入式STM32控制电梯面板 用点阵来显示电梯向上还是向下运动,用数码管来显示楼层数(由于灯阵显示楼层数比较困难故用数码管代替)。当按下对应的按钮,就可以去到对应层数,可上升可下降。 #include "stm32f10x.h" #include "stm32f10x_exti.h" #include "stm32f10x_it.h" #define uint unsigned int #define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10) #define 阅读详情

相关推荐

安卓模拟器绕过检测全解析:雷电、MuMu、蓝叠、逍遥、夜神与WSA完整指南

随着手机游戏和应用的普及,越来越多的用户选择在PC上通过模拟器来运行安卓应用。然而,许多应用和游戏为了防止作弊或出于安全考虑,会检测是否运行在模拟器环境中。本文将详细介绍各大主流模拟器的检测绕过方法,帮助用户在电脑上流畅体验各类安卓应用。1. 获取模拟器系统镜像2. 使用ROM厨房工具修改系统文件3. 替换模拟器的系统镜像雷电模拟器:适合游戏,推荐使用MAGISK + EdXposed方案MuMu模拟器:适合中度游戏,推荐太极框架蓝叠模拟器:适合国际应用,推荐MAGISK方案逍遥模拟器。

专注技术分享 3万+

ipc$连接失败的常见原因

<br /><br /><br /> <br /><br />以下是一些常见的导致ipc$连接失败的原因:<br /><br />1 IPC连接是Windows NT及以上系统中特有的功能,由于其需要用到Windows NT中很多DLL函数,所以不能在Windows 9.x/Me系统中运行,也就是说只有nt/2000/xp才可以相互建立ipc$连接,98/me是不能建立ipc$连接的;<br /><br />2 如果想成功的建立一个ipc$连接,就需要对方开启ipc$共享,即使是空连接也是这样,如果对方关闭

目前打算换一个工作,有招聘windows c++方向的也欢迎联系,北京、济南 最好 8582

Unity分包下载实战:AssetBundle+CDN+热更新全链路指南

分包下载是移动应用资源管理的核心技术,本质是将大体积安装包拆解为按需加载的独立资源单元,以解决用户安装意愿低、首屏启动慢、热更新不可控等关键问题。其底层依赖资源打包机制(如Unity AssetBundle)、全球分发网络(CDN)与安全热更新策略三者协同。AssetBundle提供资源隔离与依赖管理能力,CDN保障低延迟高可用下载,而热更新策略则决定版本控制、灰度发布与异常恢复的工程鲁棒性。该方案广泛应用于中重度游戏、大型工具类App及需要频繁内容迭代的商业项目,直接提升次日留存、过审成功率与用户在线时长

weixin_29762151的博客 354

matlab sap2000,MATLAB调用SAP2000-原创例子

matlab OAPI调用sap2000,修改Linear和damper的参数,计算。sap的安装目录下面有一个‘OAPI documention’文件,里面有函数和例子,照着例子结合我运行过,没发现问题。%% clean-up the workspace & command windowclear;clc;name_copy='001.sdb';%保存模型,命名为name_copyexc...

weixin_39541189的博客 1093

PCIe信号眼图总是不开?手把手教你调CTLE和DFE参数(附实测波形对比)

本文详细解析了PCIe信号眼图调试中CTLE和DFE参数的优化方法,帮助硬件工程师解决眼图无法张开的问题。通过实际案例和步骤指导,介绍了如何调整CTLE直流增益和DFE抽头系数,提升接收端均衡器性能,确保信号完整性。

weixin_26805597的博客 215

Windows系统下复现PointNet++算法

本文详细介绍了如何在Windows系统下复现PointNet++算法,内容包括程序下载、环境配置、数据集准备以及三个主要任务(语义分割、分类、部件分割)的实现步骤和常见报错解决方法。通过遵循本文的指导,用户可以顺利完成PointNet++算法的复现。

LingYi_5的博客 4326

失败的windows系统服务调用readfile():管道已结束?_windows安全初探之命名管道

原创 lengyi 合天智汇 前言:最近学校开了操作系统这门课,记录自己学习命名管道中与网络安全有关的内容。关于命名管道:“命名管道”又名“命名管线”(Named Pipes),是一种简单的进程间通信(IPC)机制,Microsoft Windows大都提供了对它的支持(但不包括Windows CE)。命名管道可在同一台计算机的不同进程之间或在跨越一个网络的不同计算机的不同进程之间,支持可靠的、单...

weixin_35945980的博客 783

Q&A | ZStack替代VMware实问实答

ZStack替代VMware实问实答

zstack_org的博客 1801

进程间通信IPC——管道(2)

(2) 写端没有全部被关闭,read 阻塞等待(不久的将来可能有数据递达,此时会让出。(2) 管道未满,write 将数据写入,并返回实际写入的字节数。(1) 管道写端被全部关闭,read 返回 0 ((1) 管道已满,write 阻塞。管道读端全部被关闭, 进程异常终止。返回实际读到的字节数。

tiffany_263的博客 190

从零到一:NI USB-8506 LIN通讯的驱动安装与硬件调试全攻略

本文详细介绍了NI USB-8506 LIN通讯设备的驱动安装与硬件调试全流程,包括硬件准备、驱动下载与配置、NI MAX设置及常见问题解决方案。通过实战应用与性能优化技巧,帮助用户快速掌握LIN通讯技术,适用于车载数据记录和自动化测试等场景。

weixin_28273593的博客 924

DOSBOX 0.74模拟器安装Windows 95

DosBox本身带有5.0版的DOS系统,启动后虚拟一个Z盘存放有Dosbox特有的外部指令,如config.com、imgmount.com等,经测试,可以顺利安装各版本的windows 3.1系统,但是不能安装win95,需要用原版的dos镜像启动才能安装。1. 获取启动盘镜像文件 下载Win95启动软盘镜像文件,名为boot.img,放到DosBox 0.74的目录下。2. 制作硬盘镜像文件

xjnzhidao的博客 9310

【Linux进程#1】IPC 进程间通信(一):管道(匿名管道&命名管道)

管道是一种用于进程间通信(IPC)的机制,允许一个进程将数据传递给另一个进程。在类Unix操作系统中,管道通常由内核提供,使用简单的读写接口。 管道分为两种类型:无名管道和命名管道 无名管道主要用于具有亲缘关系的进程(如父子进程),在创建时不需要名称,只能通过文件描述符进行访问命名管道(FIFO)则可以在任何进程之间通信,使用文件系统中的路径来标识。管道是单向的:数据在一个方向上流动,从写端(写入数据的进程)到读端(读取数据的进程

island1314的博客 2721

Open3D 使用RANSAC分割平面【2026最新版】

使用RANSAC从点云中分割平面,用segement_plane函数。博客长期更新,本文最新更新时间为:2026年2月28日。

点云侠的博客 37万+

IPC 进程间通信(一):管道(匿名管道&进程池)

进程可以通过 读/写 的方式打开同一个文件,操作系统会创建两个不同的文件对象 file,但是文件对象 file 中的内核级缓冲区、操作方法集合等并不会额外创建,而是一个文件的文件对象的内核级缓冲区、操作方法集合等通过指针直接指向另一个文件的内核级缓冲区、操作方法集合等。这样以读方式打开的文件和以写方式打开的文件共用一个内核级缓冲区进程通信的前提是不同进程看到同一份共享资源所以根据上述原理,父子进程可以看到同一份共享资源:被打开文件的内核级缓冲区。

2301_79582015的博客 1009

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Linux IPC进程间通信(一):管道

文章目录前言一.标准管道流二.无名管道三.命名管道 前言 Linux进程间通信(IPC)的一个重要方法就是管道,在学习管道之前,要理解两个概念 半双工(读端与写端必须固定) 全双工(读端与写端不固定) 不论是无名管道还是有名管道,都属于半双工管道,理解这一点非常重要。 一.标准管道流 FILE *popen(const char *__command, const char *__modes) command 代表shell指令 modes 分为 "r"读 和 "w"写 具体功能和Linux命令中的

Worthy_Wang的博客 452

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

IPC进程间通信(一)--管道

目录导论管道无名管道有名管道 导论 IPC(Inter-Process Communication):管道、信号、共享内存、消息队列、信息量、套接字 管道 管道分为:无名(匿名)管道和有名(命名)管道 区别: 管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。 如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。 命名管道是一种特...

austral_sep的博客 275

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

进程间通信(一):从IPC基础到管道通信

进程间通信(IPC)是操作系统实现进程协作的关键机制。阐述了进程隔离的必要性及通信需求,介绍了IPC的四种目的:数据传输、资源共享、事件通知和进程控制。分析了管道通信机制,包括匿名管道的工作原理、系统调用接口及实现方式。通过代码示例展示了父子进程如何通过pipe()创建管道、fork()共享文件描述符,并建立单向通信通道。强调管道符合“Linux一切皆文件”的设计理念,其本质是让不同进程访问同一块内核缓冲区。

原来是猿的成长足迹 666

进程间如何进行通信[IPC](一)使用管道(1)

进程间通信IPC(一)管道(1) 不同进程(一般指用户进程)之间的资源是独立的,在一个进程中无法直接访问另一个进程中的资源(比如读时共享,写时拷贝) 通信目的:数据传输,通知事件的发生,资源共享(涉及同步和互斥),进程控制 同步:(直接制约关系)为了完成某个任务而创建的多个进程,在某些位置上协调它们的工作次序而等待,传递信息所产生的制约关系,制约源自于它们的相互合作 异步:多道程序环境允许多个程...

ziggybowie的博客 392

IPC--进程间通信一(管道)

1.什么是管道?   管道分为无名管道和命名管道,本文中如无特殊说明均指无名管道。   管道是Linux支持的最初Unix IPC形式之一,具有以下特点:A.管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;B.只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);C.单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种...

Jensen Lee的博客 221

进程间通信IPC(一)无名管道、命名管道、消息队列

进程间通信IPC(一)无名管道、命名管道、消息队列

m0_69211839的博客 208

Linux进程间通信(一):管道与IPC基础

(1) 基本定义管道是指将一个进程连接到另一个进程的一个数据流。在逻辑上,它可以被看作是将数据从 A 进程的输出端传给 B 进程输入端的通道(2) 本质:内核缓冲区管道在内核层面的实现并非物理文件,而是内核维护的一块缓冲区当进程 A 向管道写入数据时,实际上是将数据拷贝到这块内核缓冲区中当进程 B 从管道读取数据时,实际上是从这块缓冲区中提取数据这块缓冲区的大小通常是有限的(在现代 Linux 内核中通常为 64KB,但会根据系统配置动态调整)(3) 特殊的文件类型。

cui_ruicheng的博客 422

linux进程间通信(IPC)一 管道(pipe)

前言 管道是UNIX环境中历史最悠久的进程间通信方式。本文主要说明在Linux环境上如何使用管道。阅读本文可以帮你解决以下问题: 什么是管道和为什么要有管道? 管道怎么分类? 管道的实现是什么样的? 管道有多大? 管道的大小是不是可以调整?如何调整? 什么是管道? 管道,英文为pipe。这是一个我们在学习Linux命令行的时候就会引入的一个很重要的概念。它的发明人是道格拉斯.麦克罗伊,这...

u013679159的博客 582

【Linux】进程间通信(一):IPC基础与管道机制深度剖析

本文系统地介绍了 Linux 进程间通信(IPC)的基础概念与常见机制,并对匿名管道(pipe)这一最基础、最经典的 IPC 手段进行了深入剖析。文章首先从进程地址空间隔离出发,阐明了进程间通信的必要性及其在实际开发中的典型应用场景.在核心内容部分,文章从内核实现、文件描述符模型以及进程视角多个层面,详细分析了匿名管道的工作原理:管道本质上是由内核维护的一块内存缓冲区,通过一对文件描述符(读端与写端)向用户态提供访问接口,体现了 Unix “一切皆文件”的设计思想。

半截诗的博客~ 858

进程间通信IPC(一)(半双工管道和消息队列)

引言: 之前学习的进程之间交换信息的方法只能由fork或exec传送打开文件,或者文件系统。但是这种通讯方式有局限性,接下来将说明进程之间相互通信的其他技术——IPC(InterProcessCommunication),过去UNIX系统IPC是各种进程间通信方式的统称,但是,其中极少能在所有UNIX系统中实现移植。随着POSIX和Open Group(以前是X/Open)标准化的推进和影响扩大,情况随已得到改善,但是差别仍然存在。以下将介绍几种实现所支持的不同形式的IPC。 单机版进程间通信方式: 半双

FHN优快云 756

Linux(七):进程通信IPC(一)之简单的匿名管道编写

管道是一种最基本的IPC机制,由pipe函数创建: #include <unistd.h>
 int pipe(int filedes[2]); 调用pipe函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有1个读端1个写端,然后通过filedes参数传出给用户程序两个文件描述符,filedes[0]指向管道的读端,filedes[1]指向管道的写端(很好记,就像0是标准输入1是标准输出一样)。所以管道在用户程序看起来就像一个打开的文件,通过read(filedes[0]);或者write(filede

Begin 439
上一篇: 机器学习-分类简介
下一篇: iOS-应用之间调用
张哲BJUT
博客等级 码龄15年 151粉丝 111原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值