시스템 호출을 직접 사용

시스템 호출을 직접 사용

나는 운영 체제의 시스템 호출에 대해 매우 혼란스러워합니다. "Operating System Concepts, 9th Edition"(63페이지) 책에 따르면:

그러나 대부분의 프로그래머는 이러한 수준의 세부 사항을 본 적이 없습니다. 일반적으로 애플리케이션 개발자는 애플리케이션 프로그래밍 인터페이스(API)를 기반으로 프로그램을 설계합니다.

API를 구성하는 함수는 일반적으로 애플리케이션 프로그래머를 대신하여 실제 시스템 호출을 수행합니다.

이는 프로그래머로서 시스템 호출을 직접 사용하지 않는다는 것을 의미합니다. 그런데 이렇게 시스템 콜을 직접 사용하는 방법을 알려주는 영상을 봤습니다.하나, 여기서 read|() 및 write() 시스템 호출에 액세스합니다. 그렇다면 시스템 호출을 직접 사용할 수 있습니까, 아니면 API를 사용할 수 있습니까, 아니면 둘 다 사용할 수 있습니까? ?

답변1

추가적인 맥락이 없으면 이 인용문이 어떤 수준의 추상화를 논의하고 있는지 완전히 명확하지 않습니다. 하지만 운영체제의 디자인 컨셉을 이야기한다면, 낮은 수준을 말하는 것일 수도 있습니다.

실제로 무엇이 무엇인지 스스로에게 물어 본 적이 있습니까?발생하다전화할 때 write()? 시스템 라이브러리는 이러한 값에 대해 일부 온전성 검사를 수행한 다음 결국 운영 체제 커널로 넘겨질 수 있습니다.

여기서부터 본격적으로 잡초에 빠져들기 시작합니다. 이를 수행하는 정확한 방법은 운영 체제와 실행 중인 특정 프로세서 아키텍처에 따라 달라집니다. 예를 들어 Linux 내부 사용syscall()커널에 시스템 호출 신호를 보냅니다. 하지만 다시 물어볼 수도 있습니다. syscall()지금은 어떻습니까? 대략적으로 말하면 매개변수를 표준화된 형식으로 어딘가에 저장한 다음 특권 모드로 전환하고 운영 체제 커널 어딘가에 있는 시스템 호출 처리기로 점프하는 특수 프로세서 명령을 실행합니다.


이제 이러한 모든 중개인을 제거하고 매개변수를 올바른 프로세서 레지스터에 넣고 명령을 직접 실행하는 것을 막을 수 있는 방법이 없습니다. 너한테는 규칙이 없어~ 해야 하다write(), 심지어 를 사용하십시오 syscall(). 이러한 기능은 프로세서에 관계없이 모든 Linux 및 운영 체제에 관계없이 모든 시스템에서 syscall()실행된다는 점에서 편의를 위한 것입니다 .write()

나는 아마도 당신의 책이 운영 체제 설계에 관해 이야기하고 있다면 그것이 바로 그 내용일 것이라고 생각합니다.개발자로서 그러지 마세요.필요이러한 기능을 사용하지만 대부분의 경우~ 고 싶어요. 그러나 그 이면에서는 운영 체제 표준 라이브러리의 설계자가 기능 자체를 구현해야 합니다. API 자체는 프로세서 내부를 처리할 필요가 없도록 표준화된 인터페이스입니다.

답변2

시스템 호출을 호출하는 API는 C와 인라인 어셈블리의 혼합과 같은 코드로 작성됩니다. 원한다면 동일하거나 유사한 코드를 애플리케이션에 넣을 수 있습니다.

이 관행은 드뭅니다. 이 기술은 라이브러리 종속성이 없는 완전히 독립 실행형 실행 파일이 얼마나 작은지 보여주기 위해 데모 프로그램에서 사용되지만 여전히 유용한 작업을 수행합니다.

C가 아닌 프로그래밍 언어용 런타임을 개발하는 사람들은 C 라이브러리에 대한 의존성을 피하기 위해 원시 시스템 호출을 사용하도록 선택할 수 있습니다.

GNU/Linux 세계에서 커널과 사용자 공간은 거의 완전히 별개의 프로젝트입니다. 애플리케이션이 사용하고 싶어하는 유용한 시스템 호출이 개발되었지만 애플리케이션이 이전 C 라이브러리가 있는 시스템에서 실행되어야 하고 해당 시스템 호출이 API로 노출되지 않는 상황을 상상할 수 있습니다(그러나 커널은 최신이며 시스템 호출이 있습니다). 이 경우 애플리케이션이 시스템 호출을 사용하는 유일한 방법은 시스템 호출을 자체적으로 실행하는 것입니다.

어떤 경우에는 API가 기본 시스템 호출과 직접적으로 일치하지 않으며 성능과 같은 다양한 이유로 애플리케이션 개발자가 이러한 시스템 호출을 직접 처리하기로 결정합니다.

예를 들어 GNU/Linux에서는 디렉터리에서 스트림형 객체를 열고 디렉터리 항목을 하나씩 읽는 데 사용되는 POSIX 함수가 opendir시스템 호출로 구현됩니다. 전체 디렉터리 항목 배치를 배열로 읽는 데 사용되는 함수입니다. . 누군가는 일대일 API를 거치는 대신 이와 같은 것을 직접 사용하는 데 관심이 있을 수 있습니다.readdirgetdents

매뉴얼 페이지에 대한 참고 사항 getdents:

SYNOPSIS
   int getdents(unsigned int fd, struct linux_dirent *dirp,
                unsigned int count);
   int getdents64(unsigned int fd, struct linux_dirent64 *dirp,
                unsigned int count);

[...]

NOTES
   Glibc does not provide a  wrapper  for  these  system  calls;  call  them  using
   syscall(2).   You  will need to define the linux_dirent or linux_dirent64 struc‐
   ture yourself.  However, you probably want to use readdir(3) instead.

답변3

일반적으로 애플리케이션 개발자는 애플리케이션 프로그래밍 인터페이스(API)를 기반으로 프로그램을 설계합니다.

이는 프로그래머로서 시스템 호출을 직접 사용하지 않는다는 것을 의미합니다.

아니 그건 당신을 뜻해요대개시스템 호출을 직접 사용하지 마십시오. 이를 사용할 수 있지만 프로그래밍할 때는 일반적으로 시스템 호출 대신 더 높은 수준의 라이브러리를 사용하고 해당 API의 함수를 사용합니다.

예를 들어, Gtk 애플리케이션을 작성 중이라면 다음을 사용합니다.g_fileset_content사용하는 대신 파일에 쓰기쓰다직접적으로는 사용하기가 더 쉽기 때문입니다.

그러나 더 높은 수준의 시스템 호출이 가능하더라도 작업 중인 작업에 더 적합하다고 생각되면 시스템 호출을 사용하는 것을 막을 수는 없습니다.

이는 일반적으로 개발 중인 애플리케이션이나 라이브러리의 유형에 따라 다릅니다. 새로운 저수준 라이브러리나 시스템 도구를 작성하는 경우 시스템 호출을 직접 사용하게 될 것입니다. 새로운 GUI 애플리케이션을 개발하는 경우 Gtk 또는 Qt에서 제공하는 API를 사용할 수 있습니다. 더 높은 수준의 프로그래밍 언어를 사용하는 경우 해당 API를 사용할 수 있습니다.내장오픈Python을 예로 들어 보겠습니다.

답변4

그러나 read|() 및 write() 시스템 호출에 액세스하는 이 비디오와 같이 시스템 호출을 직접 사용하는 방법을 가르치는 비디오를 본 적이 있습니다.

readWikipedia에도 호출 과 시스템 호출이 있지만 write나는 결코 그렇게 생각하지 않을 것이며 당신이 인용한 "운영 체제 개념"의 저자가 내 의견에 동의할지 의심됩니다. 이러한 함수는 POSIX API의 멤버입니다. 이러한 기능을 사용하는 C 코드는 POSIX 호환 시스템에서 이식 가능합니다. API는 이러한 기능의 기계 및 장치별 특성을 숨깁니다. read구현은 write시스템마다 다르며 해당 구현에서는 시스템 호출이 거의 확실합니다. read그러나 이것이 그런 의미는 아니며 write둘 다 시스템 호출입니다.

관련 정보