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

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

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

질문

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

답변1

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

그러나 프로그램이 이미 실행 중이라고 결정하는 방식을 알고 있고 그 방식이 영향을 줄 수 있는 경우 실제로 새 프로세스를 시작하거나 시작하지 않는 실행 파일을 얻을 수 있습니다.

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

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

많은 간단한 자체 개발 애플리케이션은 단순히 쿼리를 통해 다른 버전이 이미 실행되고 있는지 확인합니다 ps. 이는 다양한 방법으로 우회될 수 있습니다. 산업용 소프트웨어의 문제점은 사용자가 특정 응용 프로그램이 이미 사용 중인지 여부를 어떻게 결정하는지 거의 알 수 없다는 것입니다. 실행 파일이 상호 작용하는 열려 있는 모든 파일을 검사할 수 있는 Unix에서도 애플리케이션이 실행 중이라는 사실을 기록하는 파일이 무엇인지 알아낼 수 있다는 보장은 없습니다.

답변2

프로세스는 프로그램의 인스턴스입니다. 프로그램은 여러 번 인스턴스화될 수 있습니다. 즉, 동일한 실행 코드가 로드되어 여러 프로세스가 생성될 수 있습니다.나는 다음의 한 구절을 인용하고 싶다.리눅스 커널 이해다니엘 P. 보베(Daniel P. Bovet)와 마르코 체사티(Marco Cesati) 지음:

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

기본적으로 이는 프로그램이달리다여러 경우에 단일 인스턴스는 한 번에 하나의 실행 코드만 로드할 수 있습니다. 그럼 거기서부터 이렇게 말할 수 있겠네요.아무것도 아님프로그램을 금지할 이유가 전혀 없기 때문에 프로그램이 여러 인스턴스로 실행되는 것을 방지합니다. 물론 이러한 프로세스는 실행 코드 외에는 아무것도 공유하지 않습니다. 메모리 페이지, 파일 설명자(동일한 파일과 관련될 수 있음) 등은 프로세스마다 완전히 독립적입니다.

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

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

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

그러나 각 프로세스는 한 가지 사실을 알고 있습니다. 즉, 시스템은 커널에 의해 실행되고 커널의 서비스는 CPU에서 작업하는 데 소요되는 모든 시간 동안 프로세스가 처리합니다. 덕분에 다음과 같은 프로세스가 가능합니다.질문동일한 실행 파일의 인스턴스로 실행되는 다른 프로세스에 대한 커널. 내 마음에 떠오르는 첫 번째 해결책은 가상 파일 시스템을 읽는 것입니다 /proc. 이 FS는 사용자/애플리케이션과 커널 사이의 인터페이스처럼 작동합니다(이러한 파일은 커널 구조와 데이터를 나타내기 때문입니다). 이 파일 시스템에서 각 프로세스에는 디렉터리(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(소켓, 메시지 큐 등)를 사용하는 경우 이를 사용하여 사용자가 다음과 같은 것을 요청했음을 알릴 수 있습니다. 그것은 할 필요가 있습니다.

관련 정보