Linux 시스템은 다중 작업의 동시 실행을 지원하는 운영 체제로, 동시에 여러 프로세스를 실행할 수 있어 시스템 활용도와 효율성이 향상됩니다. 그러나 이러한 프로세스 간에 데이터 교환 및 협업이 필요한 경우 신호, 메시지 큐, 공유 메모리, 세마포어 등과 같은 일부 프로세스 간 통신(IPC) 방법을 사용해야 합니다. 그 중 유명한 파이프(FIFO)는 비교적 간단하고 강력한 IPC 방식으로, 두 개 이상의 프로세스가 파일의 내용과 형식에 상관 없이 파일을 통해 데이터를 전송할 수 있도록 해줍니다. 이 기사에서는 유명한 파이프의 생성, 열기, 읽기, 쓰기, 닫기 및 삭제를 포함하여 Linux 시스템의 명명된 파이프(FIFO) 방법을 소개합니다.
이름이 없는 파이프 적용의 주요 제한 사항은 이름이 없으므로 선호도가 있는 프로세스 간 통신에만 사용할 수 있다는 것입니다. 이 제한은 이름이 지정된 파이프(이름이 지정된 파이프 또는 FIFO)가 도입된 후에 극복되었습니다. FIFO는 FIFO 파일 형식으로 파일 시스템에 존재하는 연결된 경로 이름을 제공한다는 점에서 파이프와 다릅니다. 이렇게 하면 FIFO를 생성하는 프로세스와 친화력이 없더라도 해당 경로에 접근할 수 있다면 FIFO를 통해(경로에 접근할 수 있는 프로세스와 생성한 프로세스 간) 통신이 가능하다. FIFO) 따라서 FIFO를 통한 상관관계가 없습니다. 프로세스도 데이터를 교환할 수 있습니다. FIFO는 선입선출(선입선출)을 엄격하게 따른다는 점은 주목할 가치가 있습니다. 파이프와 FIFO에서 읽으면 항상 처음부터 데이터가 반환되고, 여기에 쓰면 끝에 데이터가 추가됩니다. lseek()와 같은 파일 위치 작업을 지원하지 않습니다.
파이프의 버퍼는 제한되어 있습니다(파이프 메커니즘은 메모리에 존재하며 파이프가 생성될 때 버퍼에 페이지 크기가 할당됩니다)
파이프라인이 전송하는 것은 형식화되지 않은 바이트 스트림입니다. 이를 위해서는 파이프라인의 판독기와 작성자가 메시지(또는 명령 또는 레코드)로 계산되는 바이트 수 등과 같은 데이터 형식에 미리 동의해야 합니다.
FIFO에는 여러 쓰기 프로세스와 하나의 읽기 프로세스가 있는 경우가 많습니다.
FIFO 개시 규칙:
한 문장으로 말하자면, 차단 플래그가 설정되고 이를 설정하기 위해 mkfifo가 호출되면 파이프 양쪽 끝의 읽기 및 쓰기가 별도로 열려야 하며 어느 쪽이든 열려 있지 않으면 차단됩니다. 오픈이라고 합니다.
규칙: 프로세스가 FIFO에서 데이터를 읽기 위해 FIFO 열기를 차단하는 경우 프로세스 내의 읽기 작업을 차단 플래그가 설정된 읽기 작업이라고 합니다. (이제 데이터를 읽기 위해 유명한 파이프를 열고 싶다는 의미입니다!)
FIFO를 열기 위해 프로세스가 쓰고 현재 FIFO에 데이터가 없는 경우(파이프의 양쪽 끝이 설정되었지만 쓰기 끝이 아직 데이터 쓰기를 시작하지 않은 것으로 이해할 수 있습니다!)
차단 플래그가 설정된 읽기 작업의 경우(위 규칙 참조)
방해하는 이유는 두 가지입니다
读打开的阻塞标志只对本进程第一个读操作施加作用,如果本进程内有多个读操作序列,则在第一个读操作被唤醒并完成读操作后,其它将要执行的读操作将不再阻塞,即使在执行读操作时,FIFO中没有数据也一样,此时,读操作返回0。
注:如果FIFO中有数据,则设置了阻塞标志的读操作不会因为FIFO中的字节数小于请求读的字节数而阻塞,此时,读操作会返回FIFO中现有的数据量。
约定:如果一个进程为了向FIFO中写入数据而阻塞打开FIFO,那么称该进程内的写操作为设置了阻塞标志的写操作。
对于设置了阻塞标志的写操作:
对于没有设置阻塞标志的写操作:
简单描述下上面设置了阻塞标志的逻辑
设置了阻塞标志
if (buf_to_write then if ( buf_to_write > system_buf_left ) //保证写入的原子性,要么一次性把buf_to_write全都写完,要么一个字节都不写! then block ; until ( buf_to_write else write ; fi else write ; //不管怎样,就是不断写,知道把缓冲区写满了才阻塞 fi
/pipe_read.c #include #include #include #include #include #include #include #define FIFO_NAME "/tmp/my_fifo" #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; printf("%d\n",bytes); }while(res > 0); close(pipe_fd); } else { exit(EXIT_FAILURE); } printf("Process %d finished, %d bytes read\n", getpid(), bytes); exit(EXIT_SUCCESS); }
//pipe_write.c #include #include #include #include #include #include #include #define FIFO_NAME "/tmp/my_fifo" #define BUFFER_SIZE PIPE_BUF #define TEN_MEG (1024 * 100) 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); //sleep(20); if (pipe_fd != -1) { while (bytes if (res == -1) { fprintf(stderr, "Write error on pipe\n"); exit(EXIT_FAILURE); } bytes += res; printf("%d\n",bytes); } close(pipe_fd); } else { exit(EXIT_FAILURE); } printf("Process %d finish\n", getpid()); exit(EXIT_SUCCESS); }
本文介绍了Linux 시스템의 명명된 파이프(FIFO)的方法,包括有名管道的创建、打开、读写、关闭和删除等方面。通过了解和掌握这些知识,我们可以更好地使用有名管道(FIFO)来实现进程间通信,提高系统的性能和可靠性。当然,Linux 시스템의 명명된 파이프(FIFO)还有很多其他的特性和用法,需要我们不断地学习和探索。希望本文能给你带来一些启发和帮助。
위 내용은 Linux 시스템의 명명된 파이프(FIFO)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!