이 기사의 내용은 Linux에서 몇 가지 파일 형식을 소개하는 것입니다. 특정 참고 가치가 있으므로 도움이 될 수 있습니다. [동영상 튜토리얼 추천: Linux tutorial]
Linux 시스템에는 7가지 유형의 파일 형식이 있습니다.
파이프 파일
로 구분됩니다. 파이프는 한쪽 끝에서 작성되고 다른 쪽 끝에서 읽혀집니다. 이는 단방향 데이터 전송이며 해당 데이터가 메모리에 직접 전송됩니다. 파이프는 상위 프로세스 쓰기 및 하위 프로세스 읽기와 같은 프로세스 간 통신 방법입니다. . 셸에서 익명 파이프는 ls | grep xxx
와 같은 파이프 기호 "|"입니다. 여기서 ls에 해당하는 프로세스는 이 독립 파이프라인의 상위 프로세스입니다. process group, grep 해당 프로세스는 자식 프로세스로, 부모 프로세스는 쓰고 자식 프로세스는 읽는다.
프로그래밍 언어에서 익명 파이프는 두 개의 파일 핸들 또는 파일 설명자(예: A, B)를 생성하여 구현되며, 하나의 파일 핸들은 데이터를 쓰는 데 사용됩니다(예: A 쓰기 끝, 데이터 쓰기 A는 자동으로 B로 푸시되고 다른 파일 핸들은 데이터를 읽는 데 사용됩니다(예: B). ls | grep xxx
,其中ls对应的进程是这个独立进程组中的父进程,grep对应的进程是子进程,父进程写子进程读。
在编程语言中,匿名管道是通过创建两个文件句柄或文件描述符(例如A、B)来实现的,一个文件句柄用于写数据(例如A写入端,数据写入A将自动推入B中),另一个文件句柄用于读数据(即B)。
对于命名管道,即有名称的管道,命名管道将文件保留在文件系统中,它也称为FIFO,也就是first in first out。虽然命名管道文件保留在文件系统中,但是这个文件只是使用命名管道的一个入口,在使用命名管道传输数据的时候,仍然是在内存中进行的,也就是说并不会因为保留在文件系统上命名管道的效率就低了。
在shell中,可以使用mknod
命令或mkfifo
命令创建命名管道,在写某些特殊需求的shell脚本时,命名管道非常有用。实际上,在Bash 4之后就支持协程(使用coproc命令)的功能了(ksh和zsh老早就支持协程),但是协程的需求都能通过命名管道来实现。
一般的管道都是单向通信的,无法实现双向通信的功能,也就是只能一边写一边读,不能两边都能读、写。如果要实现双向通信,可以创建两根管道(这样就有4个文件句柄,两个读端,两个写端),或者使用更方便的套接字。
套接字用来实现两端通信,正如上面分析的,可以实现双向管道的进程间通信功能。不仅如此,套接字还能通过网络实现跨主机的进程间通信功能。
套接字需要成对才有意义,也就是分为两端,每一端都有用于读、写的文件描述符(或文件句柄),相当于两根双向通信的管道。
套接字根据协议族的方式分为两大类:网络套接字(AF_INET类型,根据ipv4和ipv6分为inet4和inet6)和Unix Domain套接字(AF_UNIX类型)。当然,从协议族往下,套接字可细分为很多种类型,例如INET套接字可以分为TCP套接字、UDP套接字、链路层套接字、Raw套接字等等。其中网络套接字是网络编程的基础和核心。
对于单机的进程间通信,使用Unix Domain套接字比Inet套接字更好,因为Unix Domain套接字没有网络通信组件,也就是少了很多网络功能,它更加轻量级。实际上,某些语言在某些操作系统平台上实现的管道功能就是通过Unix Domain来实现的,可想而知其高效率。
Unix Domain套接字有两个文件句柄(例如A、B),这两个文件句柄都是同时可读、可写的句柄。进程1向A写入数据,将自动推送到B上,进程2可从B上读取从A写入的数据,同理进程2向B中写入数据将自动推送到A上,进程1可从A上读取从B写入的数据。如下:
进程1 进程2 ------------------------ A -----------> B B -----------> A
在编程语言中,创建Unix Domain Socket自然有对应的函数轻松创建(可man socketpair
)。对于bash shell,可以通过nc
mknod
명령 또는 mkfifo
명령을 사용할 수 있습니다. , 명명된 파이프 매우 유용합니다. 실제로 코루틴 기능(coproc 명령 사용)은 Bash 4부터 지원되었지만(ksh 및 zsh는 오랫동안 코루틴을 지원했습니다) 코루틴의 요구 사항은 명명된 파이프를 통해 실현될 수 있습니다. 일반 파이프라인은 단방향 통신이므로 양방향 통신의 기능을 구현할 수 없습니다. 즉, 동시에 쓰고 읽을 수만 있지만 양쪽에서 읽고 쓸 수는 없습니다. 양방향 통신을 구현하려면 두 개의 파이프를 만들거나(따라서 파일 핸들 4개, 읽기 끝 2개, 쓰기 끝 2개가 있음) 더 편리한 소켓을 사용할 수 있습니다. 위에서 분석한 것처럼 양방향 파이프의 프로세스 간 통신 기능을 구현할 수 있습니다. 뿐만 아니라 소켓은 네트워크를 통해 호스트 간에 프로세스 간 통신을 구현할 수도 있습니다. 소켓은 쌍을 이루어야 의미가 있습니다. 즉, 소켓은 두 개의 끝으로 나누어져 있습니다. 각 끝에는 읽기 및 쓰기를 위한 파일 설명자(또는 파일 핸들)가 있습니다. 방법 통신. #🎜🎜##🎜🎜# 소켓은 프로토콜 계열에 따라 네트워크 소켓(AF_INET 유형, ipv4 및 ipv6에 따라 inet4 및 inet6으로 구분됨)과 Unix 도메인 소켓(AF_UNIX 유형)의 두 가지 범주로 나뉩니다. 물론 프로토콜 계열부터 소켓은 여러 유형으로 세분화될 수 있습니다. 예를 들어 INET 소켓은 TCP 소켓, UDP 소켓, 링크 계층 소켓, 원시 소켓 등으로 나눌 수 있습니다. 그 중 네트워크 소켓은 네트워크 프로그래밍의 기초이자 핵심이다. #🎜🎜##🎜🎜#Unix Domain Socket#🎜🎜##🎜🎜#단일 머신에서 프로세스 간 통신을 위해서는 Inet 소켓보다 Unix Domain 소켓을 사용하는 것이 더 좋습니다. 왜냐하면 Unix Domain 소켓에는 네트워크가 없기 때문입니다. 많은 네트워크 기능이 부족한 통신 구성 요소는 더 가볍습니다. 실제로 특정 운영체제 플랫폼에서 일부 언어로 구현되는 파이프라인 기능은 유닉스 도메인을 통해 구현되는데, 그 효율성이 높다는 것을 상상할 수 있다. #🎜🎜##🎜🎜#Unix 도메인 소켓에는 두 개의 파일 핸들(예: A, B)이 있습니다. 두 파일 핸들 모두 동시에 읽고 쓸 수 있습니다. 프로세스 1이 A에 데이터를 쓰면 자동으로 B로 푸시됩니다. 프로세스 2는 A에서 쓴 데이터를 B에서 읽을 수 있습니다. 마찬가지로 프로세스 2가 B에 데이터를 쓰면 자동으로 A로 푸시됩니다. 프로세스 1은 읽을 수 있습니다. A에서 B에서 쓴 데이터. 다음과 같습니다: #🎜🎜#{protocol, src_addr, src_port, dest_addr, dest_port}#🎜🎜#프로그래밍 언어에서 Unix 도메인 소켓을 생성하면 자연스럽게 쉽게 생성할 수 있는 해당 기능이 있습니다(
man 소켓 쌍
일 수 있음). Bash 셸의 경우 nc
명령(NetCat)을 통해 생성하거나 간단히 두 개의 명명된 파이프를 사용하여 해당 기능을 구현할 수 있습니다. 필요한 경우 bash 셸에서 Unix 도메인 소켓을 사용하는 방법을 배울 수 있습니다. #🎜🎜##🎜🎜#네트워크 소켓#🎜🎜##🎜🎜#네트워크 간 프로세스 간 통신을 위해서는 네트워크 소켓이 필요합니다. 모든 네트워크 소켓은 소켓의 5튜플이라고 불리는 5개의 부분으로 구성됩니다. 형식은 #🎜🎜#rrreee#🎜🎜# 즉, 프로토콜, 소스 주소, 소스 포트, 대상 주소, 대상 포트입니다. #🎜🎜#소켓의 각 끝에는 커널 공간에 두 개의 버퍼가 있고(즉, 한 쌍의 소켓에는 4개의 버퍼가 있음) 각 끝에는 수신 버퍼와 전송 버퍼가 있습니다. 프로세스 1은 자신의 소켓의 송신 버퍼에 데이터를 쓰고, 이 데이터는 피어의 Recv 버퍼로 전송되며, 그런 다음 피어의 프로세스 2는 Recv 버퍼에서 데이터를 읽을 수 있으며 그 반대의 경우도 마찬가지입니다.
그러나 실제로 네트워크 소켓을 읽고 쓰기 전에 네트워크 소켓에는 여전히 몇 가지 설정이 필요합니다. 서버 소켓이 생성된 후(socket() 함수, 읽기 및 쓰기 작업을 위한 파일 핸들 또는 파일 설명자가 있음), 주소(bind() 함수를 통해)와 수신 포트(listening( ) 함수), 클라이언트는 소켓을 생성하고 직접 connect() 함수를 사용하여 서버 소켓에 대한 연결 요청을 시작하기만 하면 됩니다.
TCP 소켓의 경우 클라이언트가 연결 요청을 시작하면 이는 서버와의 3방향 핸드셰이크를 의미합니다(커널에 의해 완료되며 사용자 공간 프로세스와 아무 관련이 없음). 이 세 가지 핸드셰이크를 각각 분석합니다. 클라이언트가 처음으로 SYN 요청을 보낼 때 서버가 SYN을 받은 후 커널은 연결을 syn 대기열에 넣고 상태를 syn-recv로 설정한 다음 ack+syn을 보냅니다. 클라이언트 측에서는 클라이언트의 응답 응답을 받은 후 커널이 syn 큐에서 설정된 큐(또는 승인 큐)로 연결을 이동하고 연결 상태를 설정된 것으로 표시합니다. 마지막으로, 사용자 공간을 기다리는 프로세스는 커널이 수락 대기열에서 이를 제거할 수 있도록 accept() 시스템 호출을 시작합니다. 수락() 후 연결은 연결이 설정되었음을 나타내며, 이는 실제로 양쪽 프로세스 간의 데이터 전송을 실현할 수 있습니다.
TCP 소켓의 원리에 대한 자세한 내용은 내 다른 기사인 꼭 알아야 할 소켓 및 TCP 연결 프로세스를 참조하세요.
블록 장치는 고정 크기의 데이터 청크에 대한 무작위(순차적일 필요는 없음) 액세스로 구별되는 하드웨어 장치입니다. 고정된 크기의 청크를 블록이라고 합니다. 가장 일반적인 블록 장치는 하드 드라이브이지만 플로피 드라이브, 블루레이 리더, 플래시 메모리와 같은 다른 블록 장치도 많이 존재합니다. 이는 파일 시스템이 마운트되는 장치이며 파일 시스템은 블록 장치의 링구아 프랑카와 같습니다.
문자 장치는 바이트 단위로 연속적인 데이터 스트림을 통해 액세스됩니다. 전형적인 문자 장치는 터미널(물리적이든 가상이든 다양한 유형의 터미널이 있음)과 키보드입니다.
블록 장치와 문자 장치를 구별하는 가장 쉬운 방법은 데이터에 접근하는 방식을 살펴보는 것입니다. 블록 디바이스는 랜덤하게 접근하여 데이터를 얻을 수 있으며, 캐릭터 디바이스는 바이트 순서로 접근해야 합니다.
여기서 약간의 데이터, 저기서 약간의 데이터를 읽고 마지막으로 이를 연속적인 데이터 조각으로 묶을 수 있다면 이것은 블록 장치입니다. 하드 디스크의 데이터가 불연속적일 수 있습니다. 랜덤 액세스를 통해 데이터 조각을 얻습니다. 예를 들어, 디스크의 약간 큰 파일에서 처음 10k 데이터는 연속 데이터 블록이나 연속 섹터에 있을 수 있고 다음 10k 데이터는 해당 파일에서 멀리 떨어져 있거나 심지어 다른 실린더에 있을 수도 있습니다.
데이터 조각의 각 바이트가 액세스할 때와 동일한 바이트 순서로 되어 있다면, 즉 액세스할 때부터 데이터의 최종 처리까지 바이트 순서가 완전히 일관된다면 이는 문자 장치입니다. 즉, 문자 장치는 스트림 장치로 생각할 수 있습니다. 키보드에서 데이터를 입력하는 것과 마찬가지로 두 개의 키를 연속해서 누르면 이 두 키에 해당하는 바이트 데이터를 수신할 때 먼저 앞쪽에 입력한 후 뒤쪽에 입력해야 합니다. 마찬가지로 터미널 장치도 같은 방식으로 작동합니다. 프로그램이 터미널에 데이터를 출력할 때 프로그램은 먼저 문자 a를 출력한 다음 숫자 3을 출력합니다. 그런 다음 터미널에 표시할 때 a가 앞에 있어야 하고 앞에 3이 있어야 합니다. 뒷면.
위 내용은 Linux에서의 파일 형식 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!