posix_kill

ساخت وبلاگ

سیگنال سیگنال را با فرآیند شناسه فرآیند_ید به فرآیند ارسال کنید.

مولفه های

شناسه فرآیند

مقادیر بازگشت

در مورد موفقیت یا نادرست در مورد عدم موفقیت واقعی برمی گردد.

همچنین ببینید

  • صفحه دستی Kill (2) از سیستم POSIX ، که حاوی اطلاعات اضافی در مورد شناسه های فرآیند منفی ، PID ویژه 0 ، PID ویژ ه-1 و شماره سیگنال 0 است.

یادداشت های کاربر 12 یادداشت کمک کرده است

برای کسانی که می خواهند همه چیز را با یک الگوی خاص (Ala Killall برای لینوکس) بکشند ، چیزی شبیه به این را امتحان کنید. توجه داشته باشید که این ایده خوبی است که به جای اجرای Killall ، کاری مانند این را برای سازگاری Cross Platform انجام دهید ، زیرا Killall برای سایر Unixes همین کار را انجام می دهد ، همه چیز را می کشد.:)

function killall($match) if($match=='') retu 'no patte specified'; $match = escapeshellarg($match); exec("ps x|grep $match|grep -v grep|awk ''", $output, $ret); if($ret) retu 'you need ps, grep, and awk installed for this to work'; while(list(,$t) = each($output)) if(preg_match('/^([0-9]+)/', $t, $r)) system('kill '. $r[1], $k); if(!$k) $killed = 1;>> if($killed) retu '';> else retu "$match: no process killed";>>

تشخیص اگر نسخه دیگری از یک برنامه در حال اجرا باشد (*NIX خاص)

یک ترفند زیبا ، برای دیدن اینکه آیا روند دیگری در حال اجرا است ، ارسال آن سیگنال 0. سیگنال 0 در واقع ارسال نمی شود ، اما Kill بررسی می کند که آیا امکان ارسال سیگنال امکان پذیر است یا خیر. توجه داشته باشید که این تنها در صورتی که اجازه ارسال سیگنال به آن فرآیند را داشته باشید ، کار می کند.

استفاده عملی برای این تکنیک جلوگیری از اجرای چندین نسخه از همان برنامه است. شما PID را به روش معمول ذخیره می کنید. سپس در هنگام راه اندازی ، مقدار پرونده PID را بررسی می کنید و می بینید که آیا این روند در حال حاضر وجود دارد یا خیر.

این کاملاً ضد احمق نیست. در شرایط نادر امکان داشتن یک برنامه غیر مرتبط با همان PID بازیافت شده امکان پذیر است. اما این برنامه دیگر به احتمال زیاد سیگنال های برنامه شما را نمی پذیرد (مگر اینکه برنامه شما ریشه داشته باشد).

برای اینکه آن را تا حد امکان قابل اعتماد کنید ، می خواهید برنامه شما پرونده PID خود را در هنگام خاموش کردن حذف کند (به Register_Shutdown_Function مراجعه کنید). به این ترتیب ، تنها اگر برنامه شما خراب شود و برنامه دیگری برای استفاده از همان PID اتفاق بیفتد و برنامه دیگر حاضر به پذیرش سیگنال های برنامه شما بود ، آیا نتیجه اشتباهی می گیرید. این یک اتفاق بسیار نادر خواهد بود. این همچنین فرض می کند که پرونده PID با آن دستکاری نشده است (مانند همه برنامه هایی که به پرونده های PID متکی هستند).

همچنین استفاده از "PS X" برای تشخیص این امر امکان پذیر است ، اما استفاده از کشتن بسیار کارآمدتر است.

در اینجا روال اصلی است:

هوماگر می خواهید 100 ٪ قابلیت اطمینان ، به علاوه کارآیی داشته باشید. کاری که شما می توانید انجام دهید این است که با استفاده از Kill ، چک اولیه را انجام دهید. اگر می گوید در حال اجرا نیست ، پس شما آماده بزرگنمایی هستید. اما اگر Kill می گوید قبلاً در حال اجرا است ، می توانید از آن استفاده کنید:

// شما می توانید $ programName را از $ argv [0] $ نتیجه = shell_exec ('ps x | grep "'. $ prevpid." "| grep" ". $ programName.") ؛

با فرض اینکه برنامه شما مجوزهایی برای انجام این کار دارد. اگر آن را اجرا کنید و یک رشته خالی را برگردانید ، برنامه دیگر با استفاده از یک PID بازیافت شده ، یک ضربه گیر است و شما می خواهید بروید.

اگر اسکریپت خود را از مرورگر اجرا کنید (یعنی به عنوان یک فرآیند Apache) پارامتر SIG $ نمی تواند یکی از ثابت سیگنال های PCNTL باشد. به نظر می رسد به نظر می رسد که اجازه می دهد ثابت ها از خط فرمان استفاده شوند ("PH P-R.") اما اگر اسکریپت شما از Apache در حال اجرا است ، پس از آن با Posix_Kill ($ pid ، sigint) تماس می گیرد (و posix_get_last_error ()بازگشت 0).

به منظور بررسی نتیجه POSIX_KILL () می توانید از posix_get_last_error () استفاده کنید ، که در صورت موفقیت و کد خطای غیر صفر در غیر این صورت 0 (صفر) را برمی گرداند. برای دریافت یک پیام خطای قابل خواندن انسانی مطابق با آن کد خطا ، از شماره برگشتی توسط posix_get_last_error () به عنوان یک پارامتر به posix_sterror () استفاده کنید.

لطفاً توجه داشته باشید که یک کد غیر صفر از posix_get_last_error () به معنای وجود PID نیست. این فقط بدان معنی است که posix_kill () در سیگنال آن فرآیند مشکل داشت. به عنوان مثال ، PID ممکن است وجود داشته باشد اما این فرایند متعلق به کاربر دیگری غیر از روشی است که شما برای اجرای کد استفاده می کنید ، و شما ریشه ندارید. در این حالت خطایی دریافت خواهید کرد که می گوید شما مجاز به سیگنال آن فرآیند نیستید (عملیات مجاز نیست).

بر این اساس ، کد ارسال شده توسط جیل در اوایل اشتباه است. با توجه به مشخصات POSIX (به Ero. h در سیستم خود مراجعه کنید) ، EPERM به معنای "عملکرد مجاز نیست" است. این نباید به عنوان نشانگر وجود PID در نظر گرفته شود ، صرفاً به این معنی است که POSIX_KILL () نمی تواند این روند را نشان دهد. در هر صورت ، باید این نکته باشد که یک فرآیند با آن PID در حال اجرا است.

متأسفانه ، PHP در حال حاضر ثابت با این نام ها (مانند EPERM ، Enoent ، ESRCH و غیره) تعریف نمی کند.؛به عنوان مثال ESRCH مورد توجه Posix_Kill () است ، اما Socket_Esrch وجود ندارد ، زیرا این به معنای "چنین فرآیندی" نیست و برای سوکت معنی ندارد.

راه حل ها: * PHP Devs این ثابت ها را در نسخه آینده PHP تعریف می کند.* به دنبال ero. h در سیستم خود باشید و ثابت های خود را تعریف کنید. می توانید از یک اسکریپت برای تجزیه و تحلیل ero. h استفاده کنید و ثابت را در پرواز تعریف کنید یا یک بار کد PHP را برای تعریف آنها تولید کنید.

لطفاً توصیه کنید که تکیه بر یک ero. h خاص قابل حمل نیست. سیستم های مختلف ممکن است مقادیر عددی متفاوتی برای این ثابت ها داشته باشند. به همین دلیل PHP باید ثابت ها را در زمان تدوین تعریف کند و کد باید بتواند به نامهای ثابت اعتماد کند. فقط نام ها قابل حمل هستند ، نه مقادیر واقعی.

check whether the process is running. windows-linux function isRunning ( $pid ) $isRunning = false ; if( stcasecmp ( PHP_OS , "win" , 3 ) == 0 ) $out = []; exec ( "TASKLIST /FO LIST /FI "PID eq $pid "" , $out ); if( count ( $out )> 1 ) $isRunning = true ;>> elseif( posix_kill ( intval ( $prevPid ), 0 )) $isRunning = true ;> retu $isRunning ;> ?>

Although it appears that posix_kill() is built into all mode versions of PHP, it actually requires the "process" extension. Otherwise, you get an "undefined function" error when you call it. You might try this to make your code (more) robust on Linux: function send_signal ( int $pid , int $sig_num ) : bool if ( function_exists ( "posix_kill" ) ) retu posix_kill ( $pid , $sig_num ); exec ( "/usr/bin/kill -s $sig_num $pid 2>&1" , $junk , $retu_code ); retu ! $retu_code ;> ?>بله ، درست کار می کند وقتی $ sig_num = 0.

درست مانند کدهای خطا (EPERM ، Exist و غیره) ، شماره سیگنال در سیستم عامل های مختلف متفاوت است. به عنوان مثال در MacOS ، Sigcont 19 است. در لینوکس سیگستوپ 19 است. تفاوت بزرگ.

اگر PCNTL را در آن تهیه کرده اید ، می توانید از ثابت هایی مانند Sigcont استفاده کنید. من اعتماد دارم که همه آنها درست هستند.

اگر اینطور نیست ، به /usr/include/signal. h نگاه کنید. این روزها تن های Ifdef Mumbo Jumbo آن اما می توانید به/usr/شامل/bits یا/usr/شامل/sys یا چیزی بروید و به دنبال پرونده هایی به نام SIG*. H باشید. یکی از آنها آنها را برای شما لیست می کند.

به خاطر داشته باشید که فقط می توانید سیگنال های کشتن را به فرآیندهای متعلق به UID خود ارسال کنید.

اگر برنامه خود را به عنوان Root اجرا می کنید ، می توانید سیگنال های Kill را برای همه فرآیندها ارسال کنید.

posix_kill چندان قابل اعتماد نیست (به نظر می رسد همیشه سیگنال را تحویل می دهد - حتی 0 به یک فرآیند موجود - و خطایی ایجاد نمی کند). من این روش را برای بررسی وجود یک فرآیند ، با استفاده از /PROC پیدا کردم:

بدیهی است که مجوزها را بررسی کنید.

اگر می خواهید آزمایش کنید که آیا فرآیندهای متعلق به سایر کاربران در حال اجرا هستند ، می توانید از آنها استفاده کنید:

$running = posix_kill ( $pid , 0 ); if( posix_get_last_error ()== 1 ) /* EPERM */ $running = true ; ?>اگر این روند متعلق به شخص دیگری باشد (و شما ریشه ندارید) ، یک EPERM دریافت خواهید کرد. در سیستم من (FreeBSD) این به 1 تعریف شده است.

شما باید آزمایش کنید که مقدار EPERM در سیستم شما چیست.

در اینجا یک عملکرد کشتن فرایند برای ویندوز وجود دارد:

تابع win_kill ($ pid)<$wmi =new COM ( "winmgmts:!\\.\root\cimv2" ); $procs = $wmi > ExecQuery ( "SELECT * FROM Win32_Process WHERE ProcessId='" . $pid . "'" ); foreach( $procs as $proc ) $proc > Terminate ();> ?>

کمی عملکرد بازگشتی برای از بین بردن یک روند و فرزندانش. این برای من خوب است و من کار دیگری برای انجام آن پیدا نمی کنم. این ترکیبی از اسکریپت های مختلفی است که من پیدا کردم.

عملکرد KillProcessandChilds (PID $ ، سیگنال $)<exec (="" "ps="" -ef|="" awk="" '$3="=" '="" $pid="" ""="" ،="" $="" خروجی="" ret)="" ؛="" اگر="" ($="" بازگردد="" "به="" ps="" grep="" و="" awk"="" نیاز="" دارید="" در="" حالی="" که="" (لیست="" (،="" t)="هر" خروجی))> //echo "killing ".$pid." "; posix_kill ( $pid , 9 );> ?>

آموزش مقدماتی فارکس...
ما را در سایت آموزش مقدماتی فارکس دنبال می کنید

برچسب : نویسنده : علیرام نورایی بازدید : 54 تاريخ : جمعه 12 خرداد 1402 ساعت: 1:04