Direct IO란 무엇입니까
Direct IO는 실제로 Linux 운영 체제의 개념입니다. 파일 스트림을 직접 조작한다는 뜻인데 왜 직접적이라고 할까요? 실제로 우리 운영 체제는 파일 작업을 수행할 때 즉시 디스크에 있는 파일을 직접 읽고 쓰지 않습니다. 중간에 페이지 캐시 계층이 있습니다. 캐시이기 때문에 확실히 성능 향상을 가져올 수 있지만 이것이 완전히 절대적이지는 않습니다. 직접 작업은 이 캐시 작업 계층을 무시하고 디스크에서 파일을 직접 읽고 쓰는 것입니다. 우리 모두는 디스크, SSD의 처리 속도와 CPU 및 메모리 사이에 큰 격차가 있다는 것을 알고 있습니다. 기본 페이지 캐시는 이러한 격차를 해소하는 데 사용됩니다. 그러나 페이지 캐시는 CPU의 컴퓨팅 작업을 증가시키고 메모리를 점유합니다. 직접 작업에는 이러한 문제가 없지만 상대적으로 속도는 캐시를 사용한 파일 읽기 작업의 속도와 비교할 수 없습니다.
위 내용은 Direct IO에 대한 간단한 이해입니다. 보다 자세한 설명을 원하시면 글 마지막에 있는 참고문서의 두 번째 링크를 참고하셔서 심도있게 공부하시면 됩니다. PHP에서는 PECL에서 직접 Direct IO 확장을 다운로드하고 확장의 일반적인 설치 방법에 따라 설치합니다.
파일 생성 및 쓰기
파일 작업이므로 먼저 파일 데이터를 생성하고 쓰겠습니다.
$fd = dio_open("./test", O_RDWR | O_CREAT); echo dio_write($fd, "This is Test.I'm ZyBlog.Show me the money4i"), PHP_EOL; // 43 print_r(dio_stat($fd)); // Array // ( // [device] => 64768 // [inode] => 652548 // [mode] => 35432 // [nlink] => 1 // [uid] => 0 // [gid] => 0 // [device_type] => 0 // [size] => 43 // [block_size] => 4096 // [blocks] => 8 // [atime] => 1602643459 // [mtime] => 1602656963 // [ctime] => 1602656963 // ) dio_close($fd);
f 시리즈 함수와 유사하게, 파일을 열려면 dio_open() 함수를 사용해야 합니다. O_RDWR | O_CREAT 매개변수는 읽기-쓰기 파일을 열고 파일이 존재하지 않는 경우 생성한다는 의미입니다. 이 두 상수는 Linux에서 파일의 직접 작업과 관련된 상수에 해당하며, 기사 마지막에 있는 링크에서도 이러한 상수에 대한 설명을 볼 수 있습니다.
쓰기 작업은 dio_write()를 사용하여 완료할 수도 있습니다. 반환되는 내용은 작성된 내용의 길이입니다.
dio_stat()는 현재 파일 핸들에 대한 일부 정보를 반환합니다. 장치 번호, uid, gid, atime, mtime 및 기타 정보는 Linux에서 볼 수 있는 정보와 유사합니다. 이 파일에는 몇 가지 간단한 정보가 있습니다.
파일 읽기
파일 읽기는 함수를 이용하면 아주 간단하게 할 수 있습니다.
$fd = dio_open("./test", O_RDWR | O_CREAT); echo dio_read($fd), PHP_EOL; // This is Test.I'm ZyBlog.Show me the money4i dio_close($fd);
dio_read() 함수에는 지정된 바이트 길이에 따라 내용을 읽을 수 있는 또 다른 매개변수도 포함되어 있습니다. 관련 예제는 나중에 살펴보겠습니다.
파일 작업
파일을 읽는 동안 내용의 일부만 읽어야 하거나 특정 위치에서 파일 내용을 읽기 시작해야 할 수도 있습니다. 다음 작업 기능은 이러한 두 가지 측면에서 작동합니다.
$fd = dio_open("./test", O_RDWR | O_CREAT); var_dump(dio_truncate ($fd , 20)); // bool(true) echo dio_read($fd), PHP_EOL; // This is Test.I'm ZyB dio_seek($fd, 3); echo dio_read($fd), PHP_EOL; // s is Test.I'm ZyB dio_close($fd);
사실 이름에서 알 수 있듯이 dio_truncate()는 파일의 내용을 자르는 데 사용됩니다. 여기서는 20번째 문자부터 잘라낸 다음 dio_read()를 사용하여 처음 20자만 읽습니다.
dio_seek()는 내용 읽기를 시작할 문자를 지정합니다. 시작 문자 위치를 3으로 지정한 후에는 처음 세 문자는 읽혀지지 않습니다. dio_truncate()는 원본 파일의 내용을 수정하지만 dio_seek()는 그렇지 않습니다.
기타 설정
$fd = dio_open('./test', O_RDWR | O_NOCTTY | O_NONBLOCK); dio_fcntl($fd, F_SETFL, O_SYNC); dio_tcsetattr($fd, array( 'baud' => 9600, 'bits' => 8, 'stop' => 1, 'parity' => 0 )); while (($data = dio_read($fd, 4))!=false) { echo $data, PHP_EOL; } // This // is // Test // .I'm // ZyB dio_close($fd);
dio_fcntl() 함수는 c 함수 라이브러리에서 fcntl 함수라고 합니다. 목적은 파일 설명자에 대해 일부 지정된 작업을 수행하는 것입니다. 여기서는 F_SETFL을 사용합니다. 파일 설명자 플래그를 지정된 값으로 설정한다는 의미입니다. 이 O_SYNC는 이 설명자가 설정된 경우 데이터가 디스크에 기록될 때까지 파일 쓰기가 끝나지 않음을 의미합니다. 물론 이 함수는 다른 많은 연산자로도 설정할 수 있습니다. 자세한 내용은 PHP 공식 문서를 참조하세요.
dio_tcsetattr()은 열린 파일의 터미널 속성과 전송 속도를 설정하는 데 사용됩니다. baud는 전송 속도를 나타내고, bit는 비트를 나타내고, stop은 정지 비트를 나타내고, parity는 패리티 비트를 나타냅니다. 이 부분은 "컴퓨터 구성 원리"와 "운영 체제"에 대한 지식이 필요하므로 자세히 설명하지 않겠습니다. 여기에서 볼 수 있듯이 대학 수업에서 기본 과정은 정말 매우 중요합니다. 이러한 전문적인 기본 과정을 공부한 학생들은 이 기능의 역할을 즉시 이해할 것이라고 믿습니다.
마지막으로 dio_read()의 두 번째 매개변수를 사용하여 바이트 길이를 기준으로 파일 내용을 읽습니다. 읽은 내용이 4자 길이의 세그먼트로 출력되는 것을 볼 수 있습니다.
总结
函数的学习还是比较简单的,核心的还是要知道这个扩展在什么业务场景下更适合使用。在文章开头的介绍中我们已经说明了直接操作文件与普通文件操作的一些区别,在自缓存应用或者需要传输非常大的数据时,直接操作对于 CPU 和 内存 更加地友好。而其它情况,我们还是使用系统默认的文件操作方式就可以了。其实在大部分情况下,我们基本看不出来它们的显著区别。所以在实际应用中,还是那句话,结合业务实际情况,选择最佳的方案。
测试代码: https://github.com/zhangyue0503/dev-blog/blob/master/php/202010/source/4.PHP中DirectIO直操作文件扩展的使用.php 参考文档: https://www.php.net/manual/zh/book.dio.php https://www.ibm.com/developerworks/cn/linux/l-cn-directio/
推荐学习:《PHP视频教程》