실행 파일이 동시에 서로 다른 독립 프로세스에서 실행될 수 있는지 여부는 어떻게 결정됩니까?

실행 파일이 동시에 서로 다른 독립 프로세스에서 실행될 수 있는지 여부는 어떻게 결정됩니까?

나는 출판했다하나의 질문와인 하에서 여러 프로세스에서 독립적으로 실행 파일(PDF 뷰어)을 실행하는 방법에 대해 설명합니다(독립은 프로세스 간에 통신이 없으며 병렬 컴퓨팅이 아님을 의미합니다). 일부 회사의 PDF 편집기(향상된 뷰어 버전)에서는 이 작업을 수행할 수 없다고 들었습니다.

질문

  • 그렇다면 실행 파일이 여러 프로세스에서 독립적으로 실행될 수 있거나 실행되지 않도록 만드는 이유가 무엇인지 궁금합니다.
  • 프로그램 자체로 구현됩니까, 아니면 일부 라이브러리로 구현됩니까?
  • 운영체제에서는 이것을 구현할 수 없나요?

답변1

이는 프로그램 자체에 의해 거의 확실하게 구현되며 운영 체제가 가장 기본적인 프로그램을 제외한 모든 프로그램을 시행하는 것은 아마도 불가능할 것입니다.

그러나 프로그램이 이미 실행 중인지 확인하는 방식을 알고 있고 그 방식이 영향을 미칠 수 있는 경우 실제로 실행 파일을 가져와 새 프로세스를 시작하거나 시작하지 않을 수 있습니다.

Emacs와 같은 일부 응용 프로그램에서는 이를 특히 쉽게 수행할 수 있습니다. Emacs를 실행하는 표준 방법은 호출할 때마다 새로운 프로세스를 시작하는 것입니다. 그러나 Emacs를 서버 모드에서 명시적으로 실행한 다음 emacsclient이를 명시적으로 실행하여 기존 서버에 새 파일에 액세스하도록 지시할 수도 있습니다.

반례로 Firefox는 새 프로세스를 강제로 시작하는 명령줄 옵션을 제공하는 -no-remote반면, 기본값은 가능한 경우 이미 실행 중인 프로세스와 상호 작용하는 것입니다.

많은 간단한 기본 애플리케이션에서는 간단히 쿼리하여 이를 수행합니다 ps. 이는 여러 가지 방법으로 우회할 수 있습니다. 산업용 소프트웨어의 문제점은 사용자가 특정 응용 프로그램이 사용 중인지 여부를 어떻게 결정하는지 거의 알 수 없다는 것입니다. 실행 파일과 상호 작용하는 열려 있는 모든 파일을 검사할 수 있는 Unix에서도 애플리케이션이 실행 중이라는 사실을 기록하는 파일(있는 경우)을 파악할 수 있다는 보장은 없습니다.

답변2

프로세스는 프로그램의 인스턴스입니다. 프로그램은 여러 번 인스턴스화될 수 있습니다. 즉, 여러 프로세스를 만들고 동일한 실행 코드를 로드할 수 있습니다.인용하고 싶다Linux 커널에 대해 알아보기다니엘 P. 보베(Daniel P. Bovet)와 마르코 체사티(Marco Cesati) 작성:

프로그램과 프로세스를 구별하는 것이 중요합니다. 여러 프로세스가 동일한 프로그램을 실행할 수 있습니다.동시에, 동일한 프로세스가 여러 프로그램을 실행할 수 있음하나씩.

기본적으로 이는 프로그램이달리기어떤 경우에는 단일 인스턴스가 한 번에 하나의 실행 코드만 로드할 수 있습니다. 그래서 거기에서 우리는 말할 수 있습니다아무것도 없다비활성화할 이유가 전혀 없으므로 프로그램이 여러 인스턴스에서 실행되는 것을 방지합니다. 물론 이러한 프로세스는 코드 실행 외에는 아무것도 공유하지 않습니다. 메모리 페이지, 파일 설명자(동일한 파일을 참조할 수도 있음) 등은 프로세스마다 완전히 독립적입니다.

유닉스 계열 시스템에 관해서는 또 다른 점이 중요해 보입니다(같은 책):

유닉스 계열 운영 체제 채택프로세스/커널 모델.각 프로세스는 자신이 기계의 유일한 프로세스라고 상상합니다.이며 운영 체제 서비스에 독점적으로 액세스할 수 있습니다.

실제로 이것이 Unix 시스템에 다중 처리/다중 프로그래밍이 있는 이유입니다. 또는 적어도 이것이 이 기능의 기반이 되는 전략입니다. 따라서 이러한 사실로 인해 프로세스를 수행할 수 없습니다.선천적으로 알고 있다완전히 동일한 코드를 실행하는 다른 프로세스가 다른 CPU에서 대기 중이거나 작업 중입니다.

그러나 모든 프로세스는 한 가지 사실을 알고 있습니다. 즉, 시스템은 커널에 의해 실행되고 커널의 서비스는 프로세스가 CPU에서 작업하는 동안 항상 사용된다는 것입니다. 이 때문에 프로세스는묻다동일한 실행 파일의 인스턴스로 실행되는 다른 프로세스의 커널과 관련됩니다. 내 마음에 떠오른 첫 번째 해결책은 /proc가상 파일 시스템을 읽는 것이었습니다. 이 파일 시스템은 사용자/응용 프로그램과 커널 사이의 인터페이스처럼 작동합니다(이러한 파일은 커널 구조와 데이터를 나타내기 때문입니다). 이 파일 시스템에서 각 프로세스에는 디렉터리(PID 이름을 따서 명명됨)가 있으며 해당 디렉터리 내에서 이라는 디렉터리를 찾을 수 있습니다 exe. 예를 들어 이것은 내 bash프로세스 디렉터리인 PID 22343입니다.

lrwxrwxrwx /proc/22343/exe -> /bin/bash*

exe이제 파일 시스템을 검색하면 동일한 실행 코드를 실행하는 프로세스, 즉 동일한 실행 파일에 연결된 프로세스를 찾을 수 있습니다 .

그러나 모든 Unix 시스템이 /proc동일한 방식으로 구현되지 않기 때문에 개발자는 거의 모든 Unix 시스템이 이해하는 일반 파일에 의존하는 보다 이식 가능한 솔루션을 목표로 하고 있습니다. 이것이 .pid일반적으로 여기에 저장되는 파일입니다.

대부분의 경우 다음과 같습니다 /run.

-rw-r--r-- /run/acpid.pid
-rw-r--r-- /run/atd.pid
-rw-r--r-- /run/crond.pid

이러한 파일은 해당 파일이 속한 응용 프로그램에 의해 생성되며 프로그램 인스턴스가 실행 중인지 여부를 나타내는 표시로 사용됩니다. 일반적으로 이 파일의 내용은 실행 중인 프로세스의 PID로만 구성됩니다. 이 경우에는 PID 1503으로 실행되는 프로세스가 있는데 acpid, 이는 정확히 PID 파일에 있는 것입니다.

이제 동일한 프로그램의 모든 프로세스는 동일한 실행 코드를 공유하므로 상수(적어도 해당 값)를 공유합니다. 따라서 각 인스턴스가 PID 파일을 찾을 위치를 알고 있다면 단일 인스턴스 프로그램을 작성하는 것은 매우 쉽습니다.

if (the pid file exists) then
    send a signal to the running process or just bring it on the foreground
    exit since the work is going to be handled by the already-running process
else
    actually start the program, the first instance
endif

첫 번째 경우에 신호를 사용하는 것은 내가 가장 많이 본 동작이지만, 애플리케이션이 좀 더 복잡한 IPC(소켓, 메시지 큐...)를 사용하는 경우 이를 사용하여 사용자에게 필요한 것을 요청하고 있음을 알릴 수 있습니다. 할 것.

관련 정보