سؤال لماذا لا يمكنني قتل هذه العملية على لينكس؟


مشكلة

أود أن أقتل عملية تسمى raspivid (البرنامج الذي يسجل مقاطع الفيديو باستخدام كاميرا Raspberry Pi) ولكن لا يمكنني ...

هكذا أسميها:

#!/bin/bash

#Start recording...
raspivid -w 800 -h 600 -t 15000 -o $1 -v -n -rot 270 >> /home/pi/log/camera_output.txt 2>&1 &

#Waiting the video to be complete
sleep 16

#Killing child process
sudo kill -9 $!

#Killing parent process
sudo kill -9 $$

إذا قمت بالبحث عن هذه العملية ، فلا يزال هناك:

pi@raspberrypi ~ $ ps -ef | grep raspivid
root      7238     7234  0 21:53 ?        00:00:00 [raspivid]
pi       17096 14925  0 22:05 pts/0    00:00:00 grep --color=auto raspivid

إذا حاولت قتلها ، فإنها لا تموت. بدلا من ذلك يغير PID الأم إلى 1:

pi@raspberrypi ~ $ sudo killall raspivid
pi@raspberrypi ~ $ ps -ef | grep raspivid
root      7238     1  0 21:53 ?        00:00:00 [raspivid]
pi       17196 14925  0 22:05 pts/0    00:00:00 grep --color=auto raspivid
pi@raspberrypi ~ $ sudo killall raspivid

الملاحظات:

  1. المكالمة تعمل بشكل جيد لفترة من الوقت (ساعتان أو شيء) ثم تبدأ شنقا.
  2. فقط الطاقة الفعلية إيقاف يحل المشكلة. لا أستطيع إعادة التشغيل عبر المحطة الطرفية (توقف أيضا)

أسئلتي:

  1. لماذا يقوم Linux بتعيين معرف PID إلى 1؟
  2. لماذا لا يمكن قتل العملية؟ (لقد حاولت أيضا sudo kill -9 7238)

8
2018-02-04 21:11


الأصل




الأجوبة:


مشكلة

من المحتمل أن يتم إنشاء النص البرمجي الخاص بك الاموات الاحياء بسبب الخاص بك kill -9 الأوامر. كما اقترح من jjlin الجواب أيضا ليس من الممارسات الجيدة أن تقتل فجأة بعض العمليات دون أن تضطر إلى ذلك.

من عند man bash نستطيع القراءة:

العمليات المُعلمة <defunct> هي عمليات ميتة (تسمى "الاموات الاحياء") أن تبقى لأن والدهم لم يدمرهم بشكل صحيح.   هذه العمليات سيتم تدميرها بواسطة init (8) إذا خرجت عملية الوالدين.

الإجابة رقم 1: هذه العملية فيه لديه PID 1 و لهذا لينكس يعينهم الوالد مع PID 1 (لأنه يعينهم فيه).

الإجابة رقم 2: لا يمكن قتلهم ببساطة لأنهم فقط ميت... إذا كان والدهم init ربما يكفي أن ننتظر بعض الوقت.

لإزالة كائنات الزومبي من النظام ، يمكن إرسال إشارة SIGCHLD إلى الأصل يدويًا باستخدام الأمر kill. إذا كانت العملية الأم لا تزال ترفض جني غيبوبة ، فإن الخطوة التالية هي إزالة العملية الأم. عندما تفقد إحدى العمليات أصلها ، يصبح init العنصر الرئيسي الجديد. يقوم الإعداد بشكل دوري بتنفيذ استدعاء نظام الانتظار لجني أي زومبي باستخدام init كأصل. [1]

فقط في حالة ظهور هذه الفكرة يومًا أو لآخر: إلى #kill -9 init عملية مع امتياز الجذر هو برنامج مكافئ لفصل الكمبيوتر فعليا من شبكة الكهرباء. [:-)]

ومع ذلك عمليات غيبوبة يمكن تحديدها في إخراج ps الأمر من خلال وجود "ض" في STAT عمود. يمكنك استخدام السطر التالي لتحديدها بسهولة

ps -aux | grep Z

بعض المراجع حول لينكس عالم الكسالى:


2
2018-02-05 16:46



عملية مع PID 1 الأصل ليست زومبي. عملية تحصل على هذا الوالد عندما يكون الأبوين قتل قبل ذلك. لذلك له killall على ما يبدو يقتل الوالد ، وليس العملية التي أرادها. - Barmar
اين ترى <defunct> في ps انتاج؟ ما علاقة ذلك بهذا السؤال؟ - Barmar
Barmar لم أكن أرى. للأسف ليست المشكلة دائمًا هي بالضبط المكان الذي تبحث عنه. راجع للشغل من $! هو kill -9 دون انتظار عملية الخلفية مع الكاميرا ... بعد sleep 16 هو kill -9 ال الأبوينفجأة مرة أخرى. انها رائحة .الاموات الاحياء... بعد رائحة (:-)) يمكنك أن ترى ذلك ، مع ما يلي ps -ef فعل ، الطفل لا يزال على قيد الحياة ، ولكن قتل الوالد (-9). - Hastur
أعتقد أنك تربك العمليات اليتيمة بعمليات الزومبي ، لكنها غير مرتبطة. - Barmar
النظر مرة أخرى البرنامج النصي: هو kill -9 عملية خاصة بها. من المعقول أن نفترض أنه قُتل و <defunct> ... أكثر بعد المكالمة غير الفعالة sudo killall raspivid. من الممكن حتى ذلك raspivid يولد عملياته الخاصة التي تبقى يتيمة. راجع للشغل أنه يكفي للقيام "ps -aux | grep Z" لمعرفة ما إذا كان الاموات الاحياء أم لا ، ويجب أن تكون (كافية) لتجنب ذلك kill -9 العملية في البرنامج النصي الرئيسي. - Hastur


للإجابة على السؤال رقم 1:

عندما تولد عملية عمليات الطفل ، يكون لكل طفل PID الخاص به. معرّف PPID لكل طفل (معرف العملية الأصل) هو PID الخاص بعملية الأصل الخاصة به. إذا مات الوالد ، فسيتم عزل العمليات الفرعية. يتم انتقاء العمليات المعزول تلقائيًا بواسطة عملية init system التي تحتوي على PID من 1.


4
2018-02-05 10:50





ربما يحتوي البرنامج على جهاز الكاميرا مفتوحًا ، ومن خلال قتله بالقوة ، لم تسمح له بالتنظيف بشكل صحيح ، لذلك أصبح عالقًا الآن.

بعض الملاحظات:

  • من المستحسن عادة أن تقتل برنامجًا من خلال البدء بـ -9 ما لم تكن تعرف ما تفعله. مجرد قتل عادي (مع عدم وجود خيارات) على ما يرام.
  • لا ينبغي أن تكون هناك حاجة للقيام بأي قتل في النص الخاص بك على الإطلاق. لقد مررت بالفعل -t 15000 إلى البرنامج لتحديد طول الفيديو ، لذلك يجب أن يكون القتل الأول غير ضروري. القتل الثاني غير ضروري أيضاً لأن القوقعة ستخرج من تلقاء نفسها عندما تصل إلى نهاية النص. إذا كان البرنامج لا يخرج من تلقاء نفسه (كما ينبغي) ، فستواجه مشاكل أخرى.

0
2018-02-05 01:50