পাইথনে প্রদত্ত পিড সহ কোনও প্রক্রিয়া রয়েছে কিনা তা কীভাবে পরীক্ষা করবেন?


109

পিড কোনও বৈধ প্রক্রিয়ার সাথে মিলে যায় কিনা তা দেখার জন্য কি কোনও উপায় আছে? আমি ছাড়া অন্য কোনও উত্স থেকে একটি পিড os.getpid()পাচ্ছি এবং সেই পিডের কোনও প্রক্রিয়া মেশিনে নেই কিনা তা দেখার জন্য আমার পরীক্ষা করা দরকার।

আমার এটি ইউনিক্স এবং উইন্ডোতে উপলব্ধ হওয়া দরকার। আমি পিআইডি ব্যবহার করছে না কিনা তাও খতিয়ে দেখছি।


2
উইন্ডোজ একটি মানহীন ওএস। এই ধরণের জিনিসগুলি পোর্টেবল নয়। আপনার উভয় থাকতে পারে না জেনে আপনার অগ্রাধিকার কোনটি? একটি অগ্রাধিকার হিসাবে চয়ন করুন এবং প্রশ্ন সম্পাদনা করুন।
এস .লট

26
@ এস.লোট উইন্ডোজ হ'ল একটি মানহীন ওএস, এটি এসও-তে আমি দেখেছি এমন সবচেয়ে মূর্খ মন্তব্য ...
পাইট্র ডবরোগোস্ট

2
@ পাইওটর ডব্রোগোস্ট: আপনি কি এমন কোড সরবরাহ করতে পারেন যা পসিক্স স্ট্যান্ডার্ড ইউনিক্স এবং নন-পসিক্স স্ট্যান্ডার্ড উইন্ডোজ পরিচালনা করে? যদি তা হয় তবে দয়া করে একটি উত্তর সরবরাহ করুন যা (ক) সমস্যার সমাধান করে এবং (খ) এটি পরিষ্কার করে দেয় যে উইন্ডোজ কোনওভাবেই পসিক্স মানের সাথে অনুগত।
এস .লট

3
@ পাইওটারডব্রোগোস্ট আমার মনে হয় এস লোটের মন্তব্যটি বাজার ভাগের চেয়ে বাস্তবায়ন সম্পর্কিত বিশদ এবং এপিআই সমর্থন সম্পর্কে বেশি ছিল।
রায় টিঙ্কার

3
অন্যান্য জনপ্রিয় ওএসগুলির সাথে উইন্ডোজ অবশ্যই একে অপরের সাথে মিলের তুলনায় কম। (ওয়েব ডেভলপমেন্ট করা যে কেউ এটিকে একইভাবে কুখ্যাত মাইক্রোসফ্ট পণ্যের সাথে তুলনা করতে পারে।) তবে @ এস.লোটের প্রতিক্রিয়াতে: আমি খুব কমই উইন্ডোজের জন্য পাইথন কোড লিখি যা লিনাক্স, ওএসএক্স, বিএসডি ইত্যাদিতেও কাজ করে না বলে মনে হয়। সততার সাথে 'অগ্রাধিকার হিসাবে বেছে নেওয়া' সহায়ক পরামর্শ বলে মনে করবেন না, বিশেষত যেহেতু পাইথন প্ল্যাটফর্মের পার্থক্যগুলি যতটা সম্ভব অনুভবযোগ্য।
মাইকেল শ্যাপার

উত্তর:


162

পিডে 0 সিগন্যাল প্রেরণ যদি পিড চলমান না থাকে তবে ওএসআরর ব্যতিক্রম উত্থাপন করবে এবং অন্যথায় কিছু করবে না।

import os

def check_pid(pid):        
    """ Check For the existence of a unix pid. """
    try:
        os.kill(pid, 0)
    except OSError:
        return False
    else:
        return True

3
লিনাক্স এবং ওএসএক্সে নিশ্চিতভাবে কাজ করে, আমি উইন্ডোজের পক্ষে কথা বলতে পারি না। এটি আপনি যে অর্থে জিজ্ঞাসা করছেন সেই প্রক্রিয়াটি হারাবে না, এটি সিগন্যাল 0 প্রেরণ করে, যা মূলত "আপনি চালাচ্ছেন?"
mluebke

10
উইন্ডোজটিতে এটি অবশ্যই কার্যকরভাবে কাজ করে না, কারণ ইউনিক্সের মতো সংকেতগুলির মতো কোনও জিনিস নেই।
আলেকজান্ডার লেবেদেভ

13
সম্পূর্ণ হওয়ার জন্য, ত্রুটি নম্বরটি এটি 3 টির নিশ্চিত করার জন্য আপনারও পরীক্ষা করা উচিত (ব্যতিক্রমটি ধরুন এবং প্রথম আর্গটি পরীক্ষা করুন)। লক্ষ্য প্রক্রিয়াটি বিদ্যমান থাকলে এটি গুরুত্বপূর্ণ তবে আপনার কাছে সংকেত প্রেরণের অনুমতি নেই (যে কোনও কারণেই)।
haridsv

8
এখন উইন্ডো দ্বারা সমর্থিত। docs.python.org/library/os.html?hightlight=os.kill#os.kill
মাইকেল

15
os.kill Windows এ সমর্থিত নয়, তবে os.kill(pid, 0)একই হিসাবে os.kill(pid, signal.CTRL_C_EVENT)যা প্রক্রিয়া সমাপ্তি টানতে পারেন (অথবা ব্যর্থ)। আমি একজন পেতে OSErrorযেখানে errno==EINVALযখন আমি একটি subprocess এই চেষ্টা করুন।
জেসন আর। কুমবস

76

কটাক্ষপাত আছে psutilমডিউল:

পিউথন চলমান প্রক্রিয়া এবং সিস্টেমের ব্যবহার (সিপিইউ, মেমরি, ডিস্ক, নেটওয়ার্ক) সম্পর্কিত তথ্য পুনরুদ্ধারের জন্য সিউসিল (পাইথন সিস্টেম এবং প্রসেস ইউটিলিটিস) একটি ক্রস প্ল্যাটফর্ম লাইব্রেরি । [...] বর্তমানে এটি লিনাক্স , উইন্ডোজ , ওএসএক্স , ফ্রিবিএসডি এবং সান সোলারিস , ৩২-বিট এবং 64৪-বিট উভয় আর্কিটেকচারকে সমর্থন করে, ২.6 থেকে ৩.৪ পর্যন্ত পাইথন সংস্করণ (পাইথন ২.৪ এবং ২.৫ এর ব্যবহারকারীরা ২.১.৩ সংস্করণ ব্যবহার করতে পারে) । পিপিপি কাজ করার জন্যও পরিচিত।

এটির একটি ফাংশন রয়েছে pid_exists()যা আপনি প্রদত্ত পিডের সাথে কোনও প্রক্রিয়া বিদ্যমান কিনা তা পরীক্ষা করতে ব্যবহার করতে পারেন।

এখানে একটি উদাহরণ:

import psutil
pid = 12345
if psutil.pid_exists(pid):
    print("a process with pid %d exists" % pid)
else:
    print("a process with pid %d does not exist" % pid)

রেফারেন্সের জন্য:



আমার একটি উদাহরণ রয়েছে যেখানে উইন্ডোজে pid_exists নির্ভরযোগ্য হওয়া বন্ধ করে দিয়েছে। এটি ডেড পিডগুলি ব্যবহার হচ্ছে বলে ভুল প্রতিবেদন করছিল। আপনার psutil মডিউলটি সময়ে সময়ে আপডেট করার জন্য এটি একটি অনুস্মারক especially বিশেষত ওএস আপগ্রেড করার সময়।
ড্যামন ব্রোডি

62

mluebke কোড 100% সঠিক নয়; কিল () EPERM বাড়াতে পারে (অ্যাক্সেস অস্বীকার) এমন ক্ষেত্রে যার অর্থ সম্ভবত কোনও প্রক্রিয়া বিদ্যমান। এটি কাজ করার কথা:

(জেসন আর। কমবসের মন্তব্য অনুসারে সম্পাদিত)

import errno
import os

def pid_exists(pid):
    """Check whether pid exists in the current process table.
    UNIX only.
    """
    if pid < 0:
        return False
    if pid == 0:
        # According to "man 2 kill" PID 0 refers to every process
        # in the process group of the calling process.
        # On certain systems 0 is a valid PID but we have no way
        # to know that in a portable fashion.
        raise ValueError('invalid PID 0')
    try:
        os.kill(pid, 0)
    except OSError as err:
        if err.errno == errno.ESRCH:
            # ESRCH == No such process
            return False
        elif err.errno == errno.EPERM:
            # EPERM clearly means there's a process to deny access to
            return True
        else:
            # According to "man 2 kill" possible error values are
            # (EINVAL, EPERM, ESRCH)
            raise
    else:
        return True

আপনি উইন্ডোতে এটি করতে পারবেন না যদি আপনি পাইউইন 32, সিটিপস বা কোনও সি এক্সটেনশান মডিউল ব্যবহার না করেন। যদি আপনি কোনও বাহ্যিক লাইবের উপর নির্ভর করে ঠিক থাকেন তবে আপনি psutil ব্যবহার করতে পারেন :

>>> import psutil
>>> psutil.pid_exists(2353)
True

হরিডস্ভ পরামর্শ দেয় যে পরীক্ষাটি e.errno হওয়া উচিত! = 3; সম্ভবত e.errno! = errno.ESRCH
জেসন আর। কুম্বস

কেন? ESRCH এর অর্থ "এরকম কোনও প্রক্রিয়া নেই"।
জিম্পাওলো রোডোলা

2
ঠিক। যেহেতু ESRCH এর অর্থ "এরকম কোনও প্রক্রিয়া নেই", এররনো! = ESRCH এর অর্থ "এ জাতীয় কোনও প্রক্রিয়া নয়" বা "প্রক্রিয়া বিদ্যমান নেই", যা ফাংশনের নামের সাথে মিল রয়েছে। আপনি বিশেষত EPERM উল্লেখ করেছেন, তবে অন্যান্য সম্ভাব্য ত্রুটি কোডগুলি কী বোঝায়? এটির ত্রুটি কোডটি এক্কেবারে ভুল বলে মনে হচ্ছে যা চেকের অভিপ্রায়ের সাথে স্বচ্ছভাবে সম্পর্কিত, অন্যদিকে ESRCH এর সাথে নিবিড়ভাবে সম্পর্কিত বলে মনে হচ্ছে।
জেসন

তুমি ঠিক বলছো. আমি কোডটি সম্পাদনা করেছি যা এখন আপনার প্রস্তাবিত প্রতিফলিত করে।
জিম্পাওলো রোডোলো

python3 os.kill () মধ্যে ছোঁড়ার ProcessLookupError
martinkunev

19

প্রক্রিয়াটিতে 'সিগন্যাল 0' প্রেরণ সম্পর্কিত উত্তরগুলি কেবল তখনই কাজ করবে যদি প্রশ্নে থাকা প্রক্রিয়াটি পরীক্ষা চালানো ব্যবহারকারীর মালিকানাধীন থাকে । অন্যথায় আপনি অনুমতিগুলিরOSError কারণে অনুমতি পাবেন , এমনকি সিস্টেমে পিড বিদ্যমান থাকলেও।

এই সীমাবদ্ধতা বাইপাস করার জন্য আপনি /proc/<pid>বিদ্যমান কিনা তা পরীক্ষা করতে পারেন :

import os

def is_running(pid):
    if os.path.isdir('/proc/{}'.format(pid)):
        return True
    return False

এটি কেবল লিনাক্স ভিত্তিক সিস্টেমে প্রযোজ্য, স্পষ্টতই।


ভুল। PermissionErrorমানে পিডের অস্তিত্ব রয়েছে , ProcessLookupErrorযদি পিডের অস্তিত্ব না থাকে তবে আপনি পাবেন ।
jfs

OSErrorবঞ্চিত অনুমতি কারণে অন্যান্য বেশী থেকে পৃথকীকৃত করা যেতে পারে - হয় errno দিকে তাকিয়ে মাধ্যমে অথবা আরো বিশেষ সংক্রামক মাধ্যমে PermissionError/ ProcessLookupErrorব্যতিক্রম যা থেকে আহরণ করা OSError। ফিউটারমোর, প্রক্রিয়া বিদ্যমান থাকলে আপনি কেবল অনুমতি ত্রুটি পাবেন। সুতরাং, আপনার উদাহরণটি কেবলমাত্র একটি বিকল্প পদ্ধতি যা লিনাক্স এবং কিছু অন্যান্য ইউনিসিতে কাজ করে তবে এটি সঠিকভাবে কল করার চেয়ে বেশি সম্পূর্ণ নয় os.kill(pid, 0)
ম্যাক্সচলেপজিগ

এই সমাধানটি কর্স-প্ল্যাটফর্ম নয়। ওপি চাইছে এটি ইউনিক্স এবং উইন্ডোজে উপলভ্য হোক। /procজন্য procfs শুধুমাত্র লিনাক্স প্রস্থান করে, বাসদ বা ওএসএক্স এমনকি না।
চার্লস

এই পদ্ধতিটি ব্যর্থ হয় যদি / প্রোক্টটি হাইডপিড = 2 মাউন্ট করা থাকে তবে প্রক্রিয়াটি অন্য কোনও ব্যক্তির মালিকানাধীন থাকলে তালিকায় প্রদর্শিত হবে না।
পার্কিনস

8

পাইথন ৩.৩++ তে আপনি এর্নো কনস্ট্যান্টের পরিবর্তে ব্যতিক্রম নাম ব্যবহার করতে পারেন। পজিক্স সংস্করণ :

import os

def pid_exists(pid): 
    if pid < 0: return False #NOTE: pid == 0 returns True
    try:
        os.kill(pid, 0) 
    except ProcessLookupError: # errno.ESRCH
        return False # No such process
    except PermissionError: # errno.EPERM
        return True # Operation not permitted (i.e., process exists)
    else:
        return True # no error, we can send a signal to the process

7

উইন্ডোজ নির্দিষ্ট পদ্ধতিতে তাদের আইডি সহ চলমান প্রক্রিয়াগুলির সম্পূর্ণ তালিকা পাওয়ার জন্য এখানে দেখুন । এটা কিছু হবে

from win32com.client import GetObject
def get_proclist():
    WMI = GetObject('winmgmts:')
    processes = WMI.InstancesOf('Win32_Process')
    return [process.Properties_('ProcessID').Value for process in processes]

তারপরে আপনি এই তালিকার বিপরীতে থাকা পিড যাচাই করতে পারবেন। পারফরম্যান্স ব্যয় সম্পর্কে আমার কোনও ধারণা নেই, তাই আপনি যদি প্রায়শই পিড যাচাইকরণ করতে যাচ্ছেন তবে আপনি এটি আরও ভাল করে পরীক্ষা করতে পারেন।

* এনআইএক্স এর জন্য, কেবল ম্লুবকের সমাধানটি ব্যবহার করুন।


এটি আমার পক্ষে ভাল কাজ করেছে। আমি একটি প্রক্রিয়া নামের চেক করতে চেয়েছিলাম তাই "নাম" এর জন্য "প্রসেসআইডি" অদলবদল করেছিলাম এবং এটি সত্য বা মিথ্যা প্রত্যাবর্তনের জন্য তালিকায় একটি চেক রূপান্তরিত করেছি।
জেমসআর

6

এনটিআরআরসিসি-র উপর ভিত্তি করে আমি উইন্ডোজ সংস্করণ তৈরি করেছি যাতে এটি প্রক্রিয়া থেকে বেরিয়ে আসা কোডটি পরীক্ষা করে এবং অনুমতিগুলি পরীক্ষা করে:

def pid_exists(pid):
    """Check whether pid exists in the current process table."""
    if os.name == 'posix':
        import errno
        if pid < 0:
            return False
        try:
            os.kill(pid, 0)
        except OSError as e:
            return e.errno == errno.EPERM
        else:
            return True
    else:
        import ctypes
        kernel32 = ctypes.windll.kernel32
        HANDLE = ctypes.c_void_p
        DWORD = ctypes.c_ulong
        LPDWORD = ctypes.POINTER(DWORD)
        class ExitCodeProcess(ctypes.Structure):
            _fields_ = [ ('hProcess', HANDLE),
                ('lpExitCode', LPDWORD)]

        SYNCHRONIZE = 0x100000
        process = kernel32.OpenProcess(SYNCHRONIZE, 0, pid)
        if not process:
            return False

        ec = ExitCodeProcess()
        out = kernel32.GetExitCodeProcess(process, ctypes.byref(ec))
        if not out:
            err = kernel32.GetLastError()
            if kernel32.GetLastError() == 5:
                # Access is denied.
                logging.warning("Access is denied to get pid info.")
            kernel32.CloseHandle(process)
            return False
        elif bool(ec.lpExitCode):
            # print ec.lpExitCode.contents
            # There is an exist code, it quit
            kernel32.CloseHandle(process)
            return False
        # No exit code, it's running.
        kernel32.CloseHandle(process)
        return True

আসলে, অনুযায়ী msdn.microsoft.com/en-us/library/windows/desktop/... , GetExistCodeProcessপ্রয়োজন PROCESS_QUERY_INFORMATIONএবং PROCESS_QUERY_LIMITED_INFORMATIONপ্রবেশের অধিকার।
augustomen

নোট করুন যে কোডটি ভুল। GetExitCodeProcessএকটি হ্যান্ডেল এবং একটি পয়েন্টার গ্রহণ করে এবং এই নমুনায় এটি ExitCodeProcessদ্বিতীয় পরামিতি হিসাবে একটি কাঠামো গ্রহণ করে যখন এটি কেবলমাত্র পয়েন্টার হওয়া উচিত।
ফ্যাবিও জাদরোজনি

ওপেনপ্রসেসের পরে, গেটলাস্টআরার চেক করা ভাল ধারণা। একটি ERROR_ACCESS_DENIED এর অর্থ প্রক্রিয়াটি বিদ্যমান! এটি ব্যবহারের জন্য এখানে একটি সম্পূর্ণ উদাহরণ: gist.github.com/ociule/8a48d2a6b15f49258a87b5f55be29250
অক্টোবরে 20:50

4

মিশ্রন POSIX জন্য Giampaolo Rodolà এর উত্তর এবং Windows এর জন্য খনি আমি এই করেছেন:

import os
if os.name == 'posix':
    def pid_exists(pid):
        """Check whether pid exists in the current process table."""
        import errno
        if pid < 0:
            return False
        try:
            os.kill(pid, 0)
        except OSError as e:
            return e.errno == errno.EPERM
        else:
            return True
else:
    def pid_exists(pid):
        import ctypes
        kernel32 = ctypes.windll.kernel32
        SYNCHRONIZE = 0x100000

        process = kernel32.OpenProcess(SYNCHRONIZE, 0, pid)
        if process != 0:
            kernel32.CloseHandle(process)
            return True
        else:
            return False

উইন্ডোজ 8.1 এ উইন্ডোজ সংস্করণটি আমার জন্য কাজ করে না। আপনাকে পরীক্ষা GetExitCodeProcessকরতে হবে এবং নিশ্চিত করতে হবে যে আপনার এমনকি অ্যাক্সেস রয়েছে।
স্পিড প্লেন

kernel32.OpenProcessএকমাত্র ব্যবহার করা যথেষ্ট নয়। এখানে যেমন উল্লেখ করা হয়েছে "যদি প্রক্রিয়াটি সম্প্রতি উপস্থিত হয় তবে হ্যান্ডেলের জন্য একটি পিড এখনও উপস্থিত থাকতে পারে।" যদি kernel32.OpenProcessশূন্যের মূল্যহীন kernel32.GetExitCodeProcessদেয় তবে আমাদের প্রস্থান কোডটি চেক করার জন্য আরও প্রয়োজন ।
মেও

2

উইন্ডোজে আপনি এটি এইভাবে করতে পারেন:

import ctypes
PROCESS_QUERY_INFROMATION = 0x1000
def checkPid(pid):
    processHandle = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_INFROMATION, 0,pid)
    if processHandle == 0:
        return False
    else:
        ctypes.windll.kernel32.CloseHandle(processHandle)
    return True

প্রথমত, এই কোডটিতে আপনি প্রদত্ত পিড দিয়ে প্রক্রিয়াটির জন্য একটি হ্যান্ডেল পাওয়ার চেষ্টা করেন। যদি হ্যান্ডেলটি বৈধ হয়, তবে প্রক্রিয়াটির জন্য হ্যান্ডেলটি বন্ধ করুন এবং সত্যটিতে ফিরে আসুন; অন্যথায়, আপনি মিথ্যা ফিরে। ওপেনপ্রসেসের জন্য ডকুমেন্টেশন: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx


2

এটি লিনাক্সের জন্য কাজ করবে, উদাহরণস্বরূপ আপনি যদি বানশি চালাচ্ছেন কিনা তা পরীক্ষা করতে চান ... (বনশি একটি সঙ্গীত প্লেয়ার)

import subprocess

def running_process(process):
    "check if process is running. < process > is the name of the process."

    proc = subprocess.Popen(["if pgrep " + process + " >/dev/null 2>&1; then echo 'True'; else echo 'False'; fi"], stdout=subprocess.PIPE, shell=True)

    (Process_Existance, err) = proc.communicate()
    return Process_Existance

# use the function
print running_process("banshee")

এই পদ্ধতিটি ব্যবহার os.kill(pid, 0)বা দেখার তুলনায় তুলনামূলকভাবে স্বল্পতর /proc/{pid}। আপনার কোডটি কোনও সন্তানের কাঁটাচামচ চালানোর পরিবর্তে, সেই শিশুটিতে একটি শেল চালায়, শেলটি আপনার অতিমাত্রায় ক্ষুদ্র শিল-স্ক্রিপ্টকে ব্যাখ্যা করে, শেলটি অন্য একটি শিশুকে কাঁটাতে দেয় যা পিগ্রেপ চালায় এবং শেষ পর্যন্ত পিগ্রিপ পুনরাবৃত্তি ঘটায় /proc। আপনার উত্তর পোস্ট করা প্রশ্নের উত্তর দেয় না। ওপি পিআইডি প্রদত্ত একটি পদ্ধতি চেয়েছিল। আপনার পদ্ধতিতে একটি প্রক্রিয়া নাম প্রয়োজন।
ম্যাক্সচলেপজিগ

-2

আমি বলব যে আপনি এটি যা অর্জন করছেন তা পিআইডি ব্যবহার করুন এবং ত্রুটিগুলি নিখুঁতভাবে পরিচালনা করুন। অন্যথায়, এটি একটি ধ্রুপদী জাতি (পিআইডি বৈধ হতে পারে যখন আপনি এটি বৈধ পরীক্ষা করেন তবে পরে তাত্ক্ষণিক দূরে চলে যান)


আমার আরও সুনির্দিষ্ট হওয়া উচিত ছিল - আমি ইনভালিজিটি পরীক্ষা করছি। সুতরাং, আমি মূলত এটি দেখতে সক্ষম হতে চাই যে কোনও পিডের ব্যবহার নেই।
ইভান ফসমার্ক

1
তবে সেই উত্তর দিয়ে আপনি কী করবেন? তাত্ক্ষণিকভাবে আপনি সেই জ্ঞান অর্জন করার পরে, কিছু এই পিড ব্যবহার করতে পারে।
ড্যামিয়েন_এ_বিশ্বাসীরা

@ ড্যামিয়েন_সে_ অবিশ্বাসীরা - আমার জ্ঞান অর্জনের পরে যদি কিছু এটি ব্যবহার করে থাকে তবে তা ঠিক আছে এবং আমি বুঝতে পারি যে রেসের অবস্থা সম্পর্কে আপনি কী বলছেন তবে আমি আপনাকে নিশ্চিত করে বলতে পারি যে এটি আমার পরিস্থিতির জন্য প্রযোজ্য নয়।
ইভান ফসমার্ক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.