क्या एक प्रक्रिया को अस्थायी रूप से लिनक्स में जमाया जा सकता है?


53

मैं सोच रहा था कि क्या किसी निश्चित समय के लिए किसी भी प्रक्रिया को फ्रीज करने का कोई तरीका है?

मेरा मतलब यह है कि: क्या यह एक आवेदन के लिए संभव है (शायद रूट के रूप में चल रहा है) किसी अन्य पहले से चल रही प्रक्रिया (किसी भी प्रक्रिया, दोनों जीयूआई और कमांड लाइन) के निष्पादन को रोकने के लिए और फिर बाद में इसे फिर से शुरू करें? दूसरे शब्दों में, मैं नहीं चाहता कि कुछ समय के लिए लिनक्स शेड्यूलर द्वारा कुछ प्रक्रियाओं को निर्धारित किया जाए।

जवाबों:


81

यहाँ देखें

कर रहे हैं दो संकेत है कि एक प्रक्रिया के निष्पादन को निलंबित कर सकते हैं। एक "सुशोभित" है, और एक "बलशाली" है।

"सुशोभित" एक है SIGTSTP, और इसका उद्देश्य "अच्छी तरह से" प्रक्रिया को पूछना है, अगर यह ऐसा लगता है, तो निष्पादन को निलंबित करने के लिए जब तक कि यह प्राप्त न हो जाए SIGCONT। के मामले में SIGTSTP, प्रक्रिया SIGTSTP को अनदेखा कर सकती है और वैसे भी निष्पादित कर सकती है, इसलिए इसके लिए ऐसे प्रोग्राम से सहयोग की आवश्यकता होती है जिसे SIGTSTP को संभालने के लिए डिज़ाइन किया गया हो।

"बलशाली" एक है SIGSTOP, और इसका उद्देश्य उस प्रक्रिया से जुड़े सभी उपयोगकर्ता थ्रेड को निलंबित करना है। इस प्रक्रिया को अनदेखा करना SIGSTOPउतना ही असंभव है जितना कि इसे अनदेखा करना है SIGKILL(बाद वाला इस प्रक्रिया को बलपूर्वक मारता है)।

यहां उल्लिखित किसी भी सहित, एक मनमाना संकेत भेजने के लिए, आप कार्यक्रमों का उपयोग कर सकते हैं kill, जैसे killall, या pkill; या सिस्टम कॉल का उपयोग करें kill(2)। प्लेटफ़ॉर्म / आर्किटेक्चर / संस्करण-निर्भर विवरण और इरेटा के लिए अपने ऑपरेटिंग सिस्टम के मैनपेज़ देखें। ध्यान दें कि इन सभी आदेशों और syscall में "किल" शब्द एक गलत मिथ्या नाम है। इन आदेशों को डिज़ाइन नहीं किया गया है, विशेष रूप से, प्रक्रियाओं को समाप्त करने के लिए। वे संकेतों के कुछ लोगों को भेजकर ऐसा कर सकते हैं; लेकिन संकेतों का उपयोग किसी प्रक्रिया को समाप्त करने के अलावा कार्यक्षमता के लिए भी किया जा सकता है। उदाहरण के लिए, SIGSTOPकेवल प्रक्रिया को निलंबित करता है, और यह केवल कई संकेतों में से एक है जिसे इस तरह भेजा जा सकता है।

समय की अवधि समाप्त होने के बाद प्रक्रिया को स्वचालित रूप से फिर से शुरू करने की एक शर्त जोड़ने के लिए, आपको निगरानी प्रक्रिया को चलाने के लिए किसी प्रकार की निगरानी प्रक्रिया का उपयोग करना होगा और टाइमर सेट करना होगा, जो बाद में kill(2)फिर से कॉल करता है। SIGCONTकर्नेल को निष्पादन को फिर से शुरू करने का अनुरोध करने के लिए, संकेतित प्रक्रिया को संकेत भेजता है । ध्यान दें कि लिनक्स में सटीकता और परिशुद्धता के विभिन्न डिग्री के साथ कई समय तंत्र हैं; इसके अलावा, यदि आपका सिस्टम बहुत व्यस्त है, तो आपकी निगरानी की प्रक्रिया तब तक नहीं जा सकती है, जब तक कि उसके टाइमर की समय सीमा समाप्त नहीं हो जाती है, और इस प्रकार वेकअप में देरी हो सकती है।

यदि आप निलंबन की बहुत सटीक सटीकता और निलंबित प्रक्रिया को फिर से शुरू करने पर निर्भर करते हैं, तो आपको अपना निगरानी कार्यक्रम वास्तविक समय अनुमतियों के साथ चलाने की आवश्यकता हो सकती है ( अपनी प्रक्रिया को वास्तविक समय बनाने के बारे में जानकारी के लिए इस पृष्ठ पर देखें sched_setscheduler(2))। आप उच्च-रिज़ॉल्यूशन टाइमर का उपयोग कर सकते हैं, लिनक्स कर्नेल की एक विशेषता (जो केवल तभी उपलब्ध होती है जब आपका हार्डवेयर उनके लिए समर्थन प्रदान करता है), वास्तविक समय निर्धारण के संयोजन में, समय पर बहुत सटीक, उप-मिलीसेकंड सटीक प्राप्त करने के लिए , फिर जाग्रत करें और बहुत जल्द निगरानी प्रक्रिया को फिर से शुरू करने के लिए संकेत भेजें।

आपने यह नहीं बताया कि आप इसे लागू करने के लिए किन तकनीकों का उपयोग करना चाहते हैं। एक न्यूनतम न्यूनतम पर, आपको कम से कम बैश स्क्रिप्टिंग की आवश्यकता होगी, हालांकि आप उस तरह से बहुत ठीक-ठीक समय प्राप्त नहीं कर पाएंगे। यहाँ एक बैश "स्क्रिप्ट" (अनटाइटेड है, इसलिए कृपया सावधान रहें) जो आपकी क्वेरी की अवधारणा का एक प्रमाण है। यदि आपको सटीक समय की आवश्यकता है, तो आपको एक कार्यक्रम लिखना होगा, शायद C / C ++ या किसी अन्य मूल भाषा में, और वास्तविक समय निर्धारण और hrtimers का उपयोग करें।

#!/bin/bash
#This is the process you want to suspend.
screen -mdS child bash -c "cat /dev/urandom | base64"
#This is the process ID of the child process
THEPID=$(screen -list | grep child | cut -f1 -d'.' | sed 's/\W//g')
#Send SIGSTOP to the child process.
kill -SIGSTOP ${THEPID}
#Now it is suspended. This process will sleep for 10 seconds asynchronously, then resume the process.
screen -mdS monitor bash -c "sleep 10; kill -SIGCONT ${THEPID}"

ध्यान दें कि स्क्रिप्ट समाप्त हो जाएगी और नियंत्रण स्क्रिप्ट समाप्त हो जाएगी, लेकिन screenमॉनिटर प्रक्रिया को नियंत्रित करने के कारण , यह 10 सेकंड के लिए पृष्ठभूमि में चलती रहेगी (तर्क के आधार पर sleep) और फिर जागने और बच्चे की प्रक्रिया जारी रखें। लेकिन यह लंबे समय बाद होगा जब नियंत्रित स्क्रिप्ट समाप्त हो जाएगी। यदि आप समय बीतने के लिए समकालिक रूप से प्रतीक्षा करना चाहते हैं, तो बस दूसरी कॉल को छोड़ दें screenऔर नींद को हार्ड-कोड करें और कंट्रोलिंग स्क्रिप्ट में मार दें।

आप परीक्षण कर सकते हैं कि प्रक्रिया वास्तव में चल रही है

screen -rS child

इस स्क्रिप्ट को शुरू करने के बाद। आपको कंसोल पर कुछ भी दिखाई नहीं देगा। फिर टाइमर समाप्त होने (10 सेकंड) के बाद, यह आपकी स्क्रीन को बेस 64 डेटा (0-9 और एएफ से यादृच्छिक वर्ण) के साथ बाढ़ देगा। बाहर निकलने के लिए Ctrl + C दबाएं।


PoC बैश स्निपेट सहित बहुत अच्छा पूरा जवाब। अच्छा!
फगिसिन

अगर एक प्रक्रिया एक टीसीपी कनेक्शन की तरह नेटवर्क सत्र के बीच में जमी हो जाती है, जब यह जारी रहती है, तो क्या वह नेटवर्क सत्र दूषित या ड्रॉप हो सकता है? क्या इसके लिए कोई परिभाषित व्यवहार है?
CMCDragonkai

@cmcdragonkai क्योंकि न चलने की प्रक्रिया में, यह किसी भी fd से पढ़ या लिख ​​नहीं सकता है, लेकिन कर्नेल बाइट्स को तब तक ट्रांसफ़र करता रहता है जब तक कि इसका बफर टीसीपी सेशन में भर नहीं जाता है, यानी कर्नेल स्पेस और यूजर स्पेस के बीच कोई ट्रांसफर नहीं होता है। ठंड की प्रक्रिया अलग है https://www.kernel.org/doc/Documentation/power/freezing-of-tasks.txt
निजाम मोहम्मद

मैंने पाया है कि टीसीपी कनेक्शन प्रक्रिया को अग्रभूमि में लाने के बाद भी जारी रह सकता है (टाइमआउट एप्लिकेशन विशिष्ट हैं, वहां टीसीपी रखवाली होती है, लेकिन एप्लिकेशन-स्तरीय रख-रखाव भी होती है)। बर्फ़ीली प्रक्रियाएं, जब कंप्यूटर हाइबरनेशन या स्लीप मोड में होता है, तो इसका मतलब लगता है। क्या वह सही है?
CMCDragonkai

यह स्क्रिप्ट गैर-सहकारी कोड पर कोई प्रभाव नहीं डालती है: gist.github.com/ceremcem/864dd94b52ffe7b18da29558df4f1f5b
ceremcem

14

हां, आप इसे निलंबित करने के लिए एक प्रक्रिया को STOP संकेत भेजकर और फिर जारी रखने के लिए एक CONT कर सकते हैं।

उपयोग:

kill -STOP <pid>

kill -CONT <pid>

11

यदि आपके पास "फ्रीज" की उपयुक्त ढीली परिभाषा है, तो आप reniceकमांड को देख सकते हैं ।

Renice आपको चल रही प्रक्रियाओं की समयबद्धता को बदलने की अनुमति देता है।

सामान्य प्रक्रिया अच्छा मूल्य है। 0. अच्छा मूल्य बढ़ने से प्रक्रिया अच्छी हो जाती है, जैसे कि "आप पहले क्यों नहीं जाते"। जबकि अच्छा मूल्य घटने से एक प्रक्रिया कम अच्छी हो जाती है, जैसे कि "मेरे रास्ते से हट जाओ, मैं जल्दी में हूँ"। अच्छा मूल्य सीमा -20 से 19 है।

कोई भी अपनी प्रक्रिया को अच्छा बना सकता है। केवल रूट ही एक प्रक्रिया को कम अच्छा बना सकता है या किसी अन्य उपयोगकर्ता के निकनेस को बदल सकता है।

यदि आप 19 के लिए एक अच्छा मूल्य प्रक्रियाओं सेट यह केवल तभी चलेगा जब सिस्टम पर और कुछ नहीं करना चाहता।

यहाँ एक उदाहरण मेरे स्थानीय लिनक्स बॉक्स पर चलाया गया है।

ps -lप्रक्रियाओं का अच्छा मूल्य देखने के लिए NI कॉलम का उपयोग करें और देखें।

-> पीएस-एल
FS UID PID PPID C PRI NI ADDR SZ WCHAN TTY CMD
0 एस 29190 402 31146 0 75 0 - 16547 प्रतीक्षा पीटी / 0 बैश
0 टी 29190 1105 402 0 75 0 - 23980 फिनिश पीटी / 0 विम
0 आर 29190 794 402 0 76 0 - 15874 - पीटीएस / 0 पीएस

रनिंग renice +10vim प्रक्रिया पर यह एक निम्न प्राथमिकता पर चलाने के लिए कारण बनता है।

-> रेनिस +10 -पी 1105
1105: पुरानी प्राथमिकता 0, नई प्राथमिकता 10

-> पीएस-एल
FS UID PID PPID C PRI NI ADDR SZ WCHAN TTY CMD
0 एस 29190 402 31146 0 76 0 - 16547 वेट पीटीएस / 0 बैश
0 टी 29190 1105 402 0 95 10 - 23980 फिनिश पीटी / 0 विम
0 आर 29190 1998 402 0 78 0 - 15874 - पीटीएस / 0 पीएस

यह मानते हुए कि आप "फ्रीज" को "सिस्टम पर किसी और को परेशान न करें" के लिए खींच सकते हैं "आप कुछ इस तरह से स्क्रिप्ट कर सकते हैं:

20 -पी </ pid of interest> का त्याग
नींद <निश्चित समय>
0 -पी </ pid of interest>

(इसे रूट के रूप में चलाने के लिए याद रखें)।


ध्यान दें कि मैंने उपरोक्त ps -lआउटपुट के साथ कुछ स्वतंत्रताएं ले लीं ताकि छोटे नीले बक्से में अच्छी तरह से दिखाने के लिए दिलचस्प कॉलम मिल सकें :)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.