프로그램의 단일 인스턴스 만 실행 중인지 확인


120

프로그램의 인스턴스를 하나만 실행하는 Python 방식이 있습니까?

내가 생각해 낸 유일한 합리적인 해결책은 일부 포트에서 서버로 실행하려고 시도한 다음 동일한 포트에 바인딩하려는 두 번째 프로그램이 실패합니다. 하지만 정말 좋은 생각이 아닙니다. 아마도 이것보다 더 가벼운 것이 있을까요?

(프로그램이 때때로 실패 할 것으로 예상된다는 점을 고려하십시오. 즉, segfault- "잠금 파일"과 같은 것은 작동하지 않습니다)


1
segfault를 추적하고 수정하면 아마도 당신의 삶이 더 쉬울 것입니다. 쉬운 일이 아닙니다.
David Locke

그것은 내 라이브러리에 있지 않고 파이썬의 libxml 바인딩에 있으며 매우 부끄러워서 며칠에 한 번만 발생합니다.
Slava V

5
Python의 표준 라이브러리는 최신 UNIX 프로그램에 적합한 flock ()을 지원합니다. 포트를 여는 것은 훨씬 더 제한된 네임 스페이스의 스팟을 사용하는 반면, pidfile은 안전하게 무효화하기 위해 실행중인 프로세스를 확인해야하므로 더 복잡합니다. 무리는 문제가 없습니다.
Charles Duffy

s / UNIX / linux / 거기에 FTFY.
kaleissin 2014-08-04

답변:


100

다음 코드는 작업을 수행해야하며 크로스 플랫폼이며 Python 2.4-3.2에서 실행됩니다. Windows, OS X 및 Linux에서 테스트했습니다.

from tendo import singleton
me = singleton.SingleInstance() # will sys.exit(-1) if other instance is running

최신 코드 버전은 singleton.py 입니다. 제발 여기에 파일 버그 .

다음 방법 중 하나를 사용하여 tend를 설치할 수 있습니다.


2
답변을 업데이트하고 최신 버전에 대한 링크를 포함했습니다. 버그를 발견하면 github에 제출해 주시면 최대한 빨리 해결하겠습니다.
sorin

2
@Johny_M 덕분에, 나는 패치 발표에 최신 버전 만든 pypi.python.org/pypi/tendo을
소린

2
이 구문은 Python 2.6의 Windows에서 작동하지 않았습니다. 무엇 나를 위해 일한 것이 : 1 : 텐도 수입에서 2 싱글 : 나 singleton.SingleInstance () =
브라이언

25
이것만큼 사소한 것에 대한 또 다른 의존성? 그다지 매력적으로 들리지 않습니다.
WhyNotHugo

2
싱글 톤이 sigterm을받는 프로세스를 처리합니까 (예 : 프로세스가 너무 오래 실행되는 경우), 아니면 처리해야합니까?
JimJty 2014

43

간단한, 크로스 플랫폼 솔루션에서 발견 된 또 다른 질문 으로 zgoda :

import fcntl
import os
import sys

def instance_already_running(label="default"):
    """
    Detect if an an instance with the label is already running, globally
    at the operating system level.

    Using `os.open` ensures that the file pointer won't be closed
    by Python's garbage collector after the function's scope is exited.

    The lock will be released when the program exits, or could be
    released if the file pointer were closed.
    """

    lock_file_pointer = os.open(f"/tmp/instance_{label}.lock", os.O_WRONLY)

    try:
        fcntl.lockf(lock_file_pointer, fcntl.LOCK_EX | fcntl.LOCK_NB)
        already_running = False
    except IOError:
        already_running = True

    return already_running

S.Lott의 제안과 매우 비슷하지만 코드가 있습니다.


호기심에서 : 이것이 정말 크로스 플랫폼입니까? Windows에서 작동합니까?
Joachim Sauer

1
fcntlWindows 에는 모듈 이 없습니다 (기능을 에뮬레이션 할 수 있음).
jfs

10
팁 : 이것을 함수에 래핑하려면 'fp'가 전역이어야합니다. 그렇지 않으면 함수가 종료 된 후 파일이 닫힙니다.
cmcginty

1
@Mirko Control + Z는 응용 프로그램 (내가 알고있는 OS에서)을 종료하지 않고 일시 중단합니다. 을 사용하여 애플리케이션을 포 그라운드로 되돌릴 수 있습니다 fg. 따라서 제대로 작동하는 것처럼 들립니다 (예 : 앱이 여전히 활성 상태이지만 일시 중지되어 잠금 상태가 유지됨).
Sam Bull

1
내 상황 (Linux의 Python 3.8.3)에서이 코드는 수정이 필요했습니다.lock_file_pointer = os.open(lock_path, os.O_WRONLY | os.O_CREAT)
baziorek

30

이 코드는 Linux 전용입니다. 그것은 '추상적 인'UNIX 도메인 소켓을 사용하지만 간단하고 오래된 잠금 파일을 남기지 않습니다. 특별히 예약 된 TCP 포트가 필요하지 않기 때문에 위의 솔루션보다 선호합니다.

try:
    import socket
    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    ## Create an abstract socket, by prefixing it with null. 
    s.bind( '\0postconnect_gateway_notify_lock') 
except socket.error as e:
    error_code = e.args[0]
    error_string = e.args[1]
    print "Process already running (%d:%s ). Exiting" % ( error_code, error_string) 
    sys.exit (0) 

postconnect_gateway_notify_lock단일 인스턴스를 적용해야하는 여러 프로그램을 허용하도록 고유 문자열 을 변경할 수 있습니다.


1
Roberto, 커널 패닉 또는 하드 리셋 후 \ 0postconnect_gateway_notify_lock 파일이 부팅시 나타나지 않습니까? 제 경우에는 AF_UNIX 소켓 파일이 여전히 존재하며 이것은 전체 아이디어를 파괴합니다. 이 경우 특정 파일 이름에 대한 잠금을 획득하는 위의 솔루션은 훨씬 안정적입니다.
Danylo Gurianov 2013

2
위에서 언급 한 바와 같이,이 솔루션은 리눅스에 있지만 작동 하지 맥 OS X에서
빌랄과 올가

2
이 솔루션은 작동하지 않습니다. Ubuntu 14.04에서 시도했습니다. 2 개의 터미널 창에서 동시에 동일한 스크립트를 실행합니다. 둘 다 잘 실행됩니다.
Dimon 2016 년

1
이것은 우분투 16에서 저에게 효과적이었습니다. 그리고 어떤 방법 으로든 프로세스를 종료하면 다른 프로세스를 시작할 수 있습니다. Dimon 시험에서 뭔가 잘못한 것 같아요. (위 코드가 실행 된 후 스크립트를 절전 모드로 만드는 것을 잊었을 수 있으므로 즉시 종료되고 소켓이 해제되었습니다.)
Luke

1
수면 문제가 아닙니다. 코드는 인라인 코드로만 작동합니다. 나는 그것을 함수에 넣었다. 함수가 존재하자마자 소켓이 사라졌습니다.
Steve Cohen

25

나는 그것이 충분히 파이썬인지 모르겠지만, 정의 된 포트에서 수신하는 Java 세계에서 모든 주요 플랫폼에서 작동하고 프로그램 충돌에 문제가 없기 때문에 꽤 널리 사용되는 솔루션입니다.

포트 수신의 또 다른 장점은 실행중인 인스턴스에 명령을 보낼 수 있다는 것입니다. 예를 들어 사용자가 프로그램을 두 번째로 시작하면 실행중인 인스턴스에 명령을 보내 다른 창을 열라는 명령을 보낼 수 있습니다 (예 : Firefox가 수행하는 작업입니다. TCP 포트 또는 명명 된 파이프를 사용하는지 또는 '그래도).


또 다른 윈도우를 생성하므로이 +1, 그것은 등, 팝업, 내가 실행중인 인스턴스를 통지 할 수 있도록 특별히부터
WhyNotHugo

1
예를 들어 import socket; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.bind(('localhost', DEFINED_PORT)). OSError다른 프로세스가 동일한 포트에 바인딩되면 An 이 발생합니다.
crishoj

13

전에는 파이썬을 작성하지 않았지만 이것은 crond에 의해 두 번 이상 시작되는 것을 방지하기 위해 mycheckpoint에서 방금 구현 한 것입니다.

import os
import sys
import fcntl
fh=0
def run_once():
    global fh
    fh=open(os.path.realpath(__file__),'r')
    try:
        fcntl.flock(fh,fcntl.LOCK_EX|fcntl.LOCK_NB)
    except:
        os._exit(0)

run_once()

다른 호 (http://stackoverflow.com/questions/2959474)에 게시 한 후 Slava-N의 제안을 찾았습니다. 이것은 함수로 호출되고 실행중인 스크립트 파일 (pid 파일이 아님)을 잠그고 스크립트가 종료 될 때까지 (정상 또는 오류) 잠금을 유지합니다.


1
매우 우아합니다. 스크립트의 인수에서 경로를 가져 오도록 변경했습니다. 또한 곳의 공통점이 내장 권장 -
Jossef Harush

10

pid 파일을 사용하십시오. "/ path / to / pidfile"이라는 알려진 위치가 있으며 시작시 다음과 같은 작업을 수행합니다 (부분적으로는 제가 커피를 마시기 전부터 그렇게 열심히 일하고 싶지 않기 때문에 의사 코드).

import os, os.path
pidfilePath = """/path/to/pidfile"""
if os.path.exists(pidfilePath):
   pidfile = open(pidfilePath,"r")
   pidString = pidfile.read()
   if <pidString is equal to os.getpid()>:
      # something is real weird
      Sys.exit(BADCODE)
   else:
      <use ps or pidof to see if the process with pid pidString is still running>
      if  <process with pid == 'pidString' is still running>:
          Sys.exit(ALREADAYRUNNING)
      else:
          # the previous server must have crashed
          <log server had crashed>
          <reopen pidfilePath for writing>
          pidfile.write(os.getpid())
else:
    <open pidfilePath for writing>
    pidfile.write(os.getpid())

즉, pidfile이 존재하는지 확인하는 것입니다. 그렇지 않은 경우 해당 파일에 PID를 작성하십시오. pidfile이 존재하면 pid가 실행중인 프로세스의 pid인지 확인하십시오. 그렇다면 다른 라이브 프로세스가 실행 중이므로 종료하십시오. 그렇지 않은 경우 이전 프로세스가 중단되었으므로 기록한 다음 이전 프로세스 대신 파일에 고유 한 pid를 작성하십시오. 그런 다음 계속하십시오.


4
경쟁 조건이 있습니다. 테스트 후 쓰기 시퀀스는 두 프로그램이 거의 동시에 시작하고 파일을 찾지 않고 동시에 쓰기 위해 열려는 예외를 발생시킬 수 있습니다. 그것은 해야 다른 진행할 수 있도록 하나에 예외를 발생.
S.Lott


5

작동 할 수 있습니다.

  1. 알려진 위치에 PID 파일을 만들어보십시오. 실패하면 누군가 파일을 잠근 것입니다.

  2. 정상적으로 완료되면 다른 사람이 덮어 쓸 수 있도록 PID 파일을 닫고 제거하십시오.

프로그램이 충돌하더라도 PID 파일을 제거하는 쉘 스크립트로 프로그램을 래핑 할 수 있습니다.

또한 프로그램이 중단되면 PID 파일을 사용하여 프로그램을 종료 할 수 있습니다.


3

잠금 파일을 사용하는 것은 유닉스에서 매우 일반적인 접근 방식입니다. 충돌이 발생하면 수동으로 정리해야합니다. 파일에 PID를 저장하고 시작할 때이 PID가있는 프로세스가 있는지 확인하고 그렇지 않은 경우 잠금 파일을 재정의 할 수 있습니다. (그러나 read-file-check-pid-rewrite-file에 대한 잠금도 필요합니다.) OS 에서 pid를 얻고 확인하는 데 필요한 것을 찾을 수 있습니다. 패키지 . 주어진 pid를 가진 프로세스가 있는지 확인하는 일반적인 방법은 치명적이지 않은 신호를 보내는 것입니다.

다른 대안은 이것을 flock 또는 posix 세마포와 결합 할 수 있습니다.

saua가 제안한 것처럼 네트워크 소켓을 여는 것이 아마도 가장 쉽고 이식성이있을 것입니다.


3

사용하는 사람의 경우 wxPython을을 자신의 응용 프로그램을 위해, 당신은 기능을 사용할 수 있습니다 wx.SingleInstanceChecker 여기에 기록을 .

나는 개인적으로 서브 클래스 사용 wx.App의 사용을 만드는 wx.SingleInstanceChecker되돌아 False에서 OnInit()응용 프로그램이 이미 같은 실행의 기존 인스턴스가있는 경우를 :

import wx

class SingleApp(wx.App):
    """
    class that extends wx.App and only permits a single running instance.
    """

    def OnInit(self):
        """
        wx.App init function that returns False if the app is already running.
        """
        self.name = "SingleApp-%s".format(wx.GetUserId())
        self.instance = wx.SingleInstanceChecker(self.name)
        if self.instance.IsAnotherRunning():
            wx.MessageBox(
                "An instance of the application is already running", 
                "Error", 
                 wx.OK | wx.ICON_WARNING
            )
            return False
        return True

이것은 wx.App여러 인스턴스를 금지 하는 간단한 드롭 인 교체입니다 . 단순히 대체 사용 wx.App으로 SingleApp다음처럼 코드 :

app = SingleApp(redirect=False)
frame = wx.Frame(None, wx.ID_ANY, "Hello World")
frame.Show(True)
app.MainLoop()

싱글 톤에 대한 소켓 목록 스레드를 코딩 한 후 이걸 발견했습니다. 잘 작동하고 이미 몇 개의 프로그램에 설치했습니다. 그러나 추가 "wakeup"을 원합니다. 겹치는 창문의 큰 더미의 앞과 중앙. 또한 : "여기에 문서화 됨"링크는 매우 쓸모없는 자동 생성 문서를 가리 킵니다. 이것은 더 나은 링크입니다
RufusVS

@RufusVS 맞습니다-훨씬 더 나은 문서 링크이며 답변을 업데이트했습니다.
Matt Coubrough

3

다음은 최종 Windows 전용 솔루션입니다. 다음을 'onlyone.py'라고하는 모듈에 넣으십시오. 해당 모듈을 __ main __ python 스크립트 파일에 직접 포함하십시오.

import win32event, win32api, winerror, time, sys, os
main_path = os.path.abspath(sys.modules['__main__'].__file__).replace("\\", "/")

first = True
while True:
        mutex = win32event.CreateMutex(None, False, main_path + "_{<paste YOUR GUID HERE>}")
        if win32api.GetLastError() == 0:
            break
        win32api.CloseHandle(mutex)
        if first:
            print "Another instance of %s running, please wait for completion" % main_path
            first = False
        time.sleep(1)

설명

코드는 스크립트의 전체 경로에서 파생 된 이름으로 뮤텍스를 생성하려고합니다. 실제 파일 시스템과의 잠재적 인 혼동을 피하기 위해 슬래시를 사용합니다.

장점

  • 구성이나 '마법의'식별자가 필요하지 않으며 필요한만큼 다양한 스크립트에서 사용하십시오.
  • 주변에 오래된 파일이 남아 있지 않으면 뮤텍스가 함께 죽습니다.
  • 기다릴 때 유용한 메시지를 인쇄합니다.

3

Windows에서 이에 대한 가장 좋은 해결책은 @zgoda가 제안한대로 뮤텍스를 사용하는 것입니다.

import win32event
import win32api
from winerror import ERROR_ALREADY_EXISTS

mutex = win32event.CreateMutex(None, False, 'name')
last_error = win32api.GetLastError()

if last_error == ERROR_ALREADY_EXISTS:
   print("App instance already running")

일부 답변 fctnl은 Windows에서 사용할 수없는 (@sorin tendo 패키지에도 포함되어 있음) 사용하며 pyinstaller정적 가져 오기를 수행 하는 것과 같은 패키지를 사용하여 Python 앱을 고정하려고 하면 오류가 발생합니다.

또한 잠금 파일 방법을 사용하면 read-only데이터베이스 파일에 문제가 발생합니다 sqlite3.


2

나는 새로운 사용자이고 Stack Overflow가 아직 투표를 허용하지 않기 때문에 이것을 답변으로 게시하고 있습니다.

Sorin Sbarnea의 솔루션은 OS X, Linux 및 Windows에서 작동하며 그것에 대해 감사합니다.

그러나 tempfile.gettempdir ()은 OS X 및 Windows에서 한 가지 방식으로 작동하고 다른 some / many / all (?) * nixes에서 다른 방식으로 작동합니다 (OS X도 Unix라는 사실을 무시합니다!). 차이점은이 코드에서 중요합니다.

OS X 및 Windows에는 사용자 별 임시 디렉토리가 있으므로 한 사용자가 만든 임시 파일은 다른 사용자에게 표시되지 않습니다. 대조적으로 * nix의 많은 버전 (우분투 9, RHEL 5, OpenSolaris 2008 및 FreeBSD 8을 테스트했습니다)에서 임시 디렉토리는 모든 사용자에 대해 / tmp입니다.

즉, 잠금 파일이 다중 사용자 시스템에서 생성 될 때 / tmp에 생성되고 잠금 파일을 처음 생성 한 사용자 만 애플리케이션을 실행할 수 있습니다.

가능한 해결책은 잠금 파일의 이름에 현재 사용자 이름을 포함하는 것입니다.

포트를 잡는 OP의 솔루션이 다중 사용자 시스템에서도 오작동한다는 점은 주목할 가치가 있습니다.


일부 독자 (예 : 나)에게 원하는 동작은 관련된 사용자 수에 관계없이 하나의 사본 만 실행할 수 있다는 것입니다. 따라서 사용자 별 tmp 디렉토리는 손상되고 공유 / tmp 또는 포트 잠금은 원하는 동작을 나타냅니다.
Jonathan Hartley


1

나는 파일 시스템에 부딪히지 않고 프로세스 그룹을 사용하는 좋은 POSIXy 솔루션이 있어야한다고 계속해서 의심하고 있지만, 그럴 수는 없다. 다음과 같은 것 :

시작시 프로세스는 특정 그룹의 모든 프로세스에 'kill -0'을 보냅니다. 그러한 프로세스가 있으면 종료됩니다. 그런 다음 그룹에 합류합니다. 다른 프로세스는 해당 그룹을 사용하지 않습니다.

그러나 여기에는 경쟁 조건이 있습니다. 여러 프로세스가 모두 정확하게 동시에이 작업을 수행 할 수 있으며 결국 모두 그룹에 합류하여 동시에 실행됩니다. 방수 처리를 위해 일종의 뮤텍스를 추가 할 때까지 더 이상 프로세스 그룹이 필요하지 않습니다.

프로세스가 매분 또는 매시간 cron으로 만 시작되는 경우 허용 될 수 있지만 원하지 않는 날에 정확하게 잘못 될 수 있다는 사실이 저를 조금 긴장하게 만듭니다.

누군가가 그것을 개선 할 수 없다면 결국 이것은 아주 좋은 해결책이 아닐까요?


1

지난주에이 정확한 문제에 부딪 혔고 좋은 해결책을 찾았지만 매우 간단하고 깨끗한 파이썬 패키지를 만들기로 결정하고 PyPI에 업로드했습니다. 모든 문자열 리소스 이름을 잠글 수 있다는 점에서 tendo와 다릅니다. __file__동일한 효과를 얻기 위해 확실히 잠글 수 있지만 .

다음으로 설치 : pip install quicklock

사용은 매우 간단합니다.

[nate@Nates-MacBook-Pro-3 ~/live] python
Python 2.7.6 (default, Sep  9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from quicklock import singleton
>>> # Let's create a lock so that only one instance of a script will run
...
>>> singleton('hello world')
>>>
>>> # Let's try to do that again, this should fail
...
>>> singleton('hello world')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/nate/live/gallery/env/lib/python2.7/site-packages/quicklock/quicklock.py", line 47, in singleton
    raise RuntimeError('Resource <{}> is currently locked by <Process {}: "{}">'.format(resource, other_process.pid, other_process.name()))
RuntimeError: Resource <hello world> is currently locked by <Process 24801: "python">
>>>
>>> # But if we quit this process, we release the lock automatically
...
>>> ^D
[nate@Nates-MacBook-Pro-3 ~/live] python
Python 2.7.6 (default, Sep  9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from quicklock import singleton
>>> singleton('hello world')
>>>
>>> # No exception was thrown, we own 'hello world'!

살펴보기 : https://pypi.python.org/pypi/quicklock


1
방금 "pip install quicklock"을 통해 설치했지만 "from quicklock import singleton"을 통해 사용하려고하면 "ImportError : cannot import name 'singleton'"예외가 발생합니다. 이것은 Mac에 있습니다.
grayaii

퀵록은 파이썬 3에서 작동하지 않는 것으로 밝혀졌습니다. 그것이 저에게 실패한 이유입니다.
grayaii

예, 죄송합니다. 미래 보장이 전혀 없습니다. 나는 그것이 작동하도록 기여를 환영 할 것이다!
Nate Ferrero

1

Roberto Rosario의 답변을 바탕으로 다음과 같은 기능을 제안합니다.

SOCKET = None
def run_single_instance(uniq_name):
    try:
        import socket
        global SOCKET
        SOCKET = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        ## Create an abstract socket, by prefixing it with null.
        # this relies on a feature only in linux, when current process quits, the
        # socket will be deleted.
        SOCKET.bind('\0' + uniq_name)
        return True
    except socket.error as e:
        return False

SOCKET전체 프로세스가 종료 될 때만 가비지 수집되므로 글로벌 vaiable 을 정의해야합니다 . 함수에서 지역 변수를 선언하면 함수가 종료 된 후 범위를 벗어나 소켓이 삭제됩니다.

나는 그의 코드를 명확하고 정교하게 설명하기 때문에 모든 신용은 Roberto Rosario에게 가야합니다. 그리고이 코드는 https://troydhanson.github.io/network/Unix_domain_sockets.html 에서 인용 된 다음 텍스트가 설명 하는 것처럼 Linux에서만 작동 합니다.

Linux에는 특별한 기능이 있습니다. UNIX 도메인 소켓의 경로 이름이 널 바이트 \ 0으로 시작하면 해당 이름이 파일 시스템에 매핑되지 않습니다. 따라서 파일 시스템의 다른 이름과 충돌하지 않습니다. 또한 서버가 추상 네임 스페이스에서 UNIX 도메인 수신 소켓을 닫으면 해당 파일이 삭제됩니다. 일반 UNIX 도메인 소켓을 사용하면 서버가 파일을 닫은 후에도 파일이 유지됩니다.


0

리눅스 예

이 방법은 응용 프로그램을 닫은 후 자동으로 삭제되는 임시 파일 생성을 기반으로합니다. 프로그램 시작 우리는 파일의 존재를 확인합니다. 파일이 존재하면 (보류중인 실행이 있음) 프로그램이 닫힙니다. 그렇지 않으면 파일을 만들고 프로그램 실행을 계속합니다.

from tempfile import *
import time
import os
import sys


f = NamedTemporaryFile( prefix='lock01_', delete=True) if not [f  for f in     os.listdir('/tmp') if f.find('lock01_')!=-1] else sys.exit()

YOUR CODE COMES HERE

1
Stack Overflow에 오신 것을 환영합니다! 이 답변이 정확할 수 있지만 설명을 추가해주세요. 기본 논리를 전달하는 것은 단순히 코드를 제공하는 것보다 더 중요합니다. OP와 다른 독자가이 문제와 유사한 문제를 스스로 해결하는 데 도움이되기 때문입니다.
CodeMouse92

이 스레드가 안전한가요? 수표 및 임시 파일 생성은 원자되지 않습니다처럼 ... 보인다
coppit

0

Linux 시스템 pgrep -a에서는 인스턴스 수를 요청할 수도 있으며 스크립트는 프로세스 목록에서 찾을 수 있습니다 (옵션 -a는 전체 명령 줄 문자열을 나타냄). 예

import os
import sys
import subprocess

procOut = subprocess.check_output( "/bin/pgrep -u $UID -a python", shell=True, 
                                   executable="/bin/bash", universal_newlines=True)

if procOut.count( os.path.basename(__file__)) > 1 :        
    sys.exit( ("found another instance of >{}<, quitting."
              ).format( os.path.basename(__file__)))

-u $UID제한이 모든 사용자에게 적용되어야하는 경우 제거하십시오 . 면책 조항 : a) 스크립트의 (기본) 이름이 고유하다고 가정합니다. b) 경쟁 조건이있을 수 있습니다.


-1
import sys,os

# start program
try:  # (1)
    os.unlink('lock')  # (2)
    fd=os.open("lock", os.O_CREAT|os.O_EXCL) # (3)  
except: 
    try: fd=os.open("lock", os.O_CREAT|os.O_EXCL) # (4) 
    except:  
        print "Another Program running !.."  # (5)
        sys.exit()  

# your program  ...
# ...

# exit program
try: os.close(fd)  # (6)
except: pass
try: os.unlink('lock')  
except: pass
sys.exit()  

2
Stack Overflow에 오신 것을 환영합니다! 이 코드 블록이 질문에 답할 수 있지만 그 이유에 대해 약간의 설명을 제공 할 수 있다면 가장 좋습니다. 제발 편집 등의 설명을 포함하는 답변을.
Artjom B.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.