किस क्रम में मुझे शटडाउन प्रक्रियाओं को संकेत भेजना चाहिए?


88

एक अन्य प्रश्न के उत्तर पर टिप्पणी में , टिप्पणीकार कहता है:

जब तक बिल्कुल आवश्यक नहीं किल -9 का उपयोग न करें! SIGKILL फंस नहीं सकता है इसलिए मारे गए प्रोग्राम को अस्थायी फाइलों को मिटाने के लिए कोई शटडाउन रूटीन नहीं चला सकता है। पहले HUP (1), फिर INT (2), फिर QUIT (3) आज़माएँ

मैं सिद्धांत रूप में सहमत हूं SIGKILL, लेकिन बाकी मेरे लिए खबर है। यह देखते हुए कि डिफ़ॉल्ट संकेत द्वारा भेजा गया killहै SIGTERM, मुझे उम्मीद है कि यह एक मनमाना प्रक्रिया के सुंदर बंद के लिए सबसे आम तौर पर अपेक्षित संकेत है। इसके अलावा, मैंने SIGHUPगैर-समाप्ति कारणों के लिए उपयोग किया है, जैसे कि एक डेमन को "आपकी कॉन्फिग फ़ाइल को फिर से पढ़ना" बताना। और यह मुझे लगता है कि SIGINT(वही अवरोध जो आप आमतौर पर Ctrl-C, अधिकार के साथ प्राप्त करेंगे?) उतना व्यापक रूप से समर्थित नहीं है जितना इसे होना चाहिए, या इसे अपमानजनक रूप से समाप्त करना चाहिए।

यह देखते हुए कि SIGKILLएक अंतिम उपाय है - कौन से संकेत, और किस क्रम में , आपको एक मनमानी प्रक्रिया को भेजना चाहिए, ताकि इसे यथासंभव सुंदर तरीके से बंद किया जा सके?

यदि आप कर सकते हैं तो कृपया अपने उत्तरों को सहायक तथ्यों (व्यक्तिगत पसंद या राय से परे) या संदर्भों के साथ प्रमाणित करें।

नोट: मैं विशेष रूप से सर्वश्रेष्ठ प्रथाओं में दिलचस्पी रखता हूं जिनमें बैश / साइगविन के विचार शामिल हैं।

संपादित करें: अब तक, कोई भी INT या QUIT का उल्लेख नहीं करता है, और HUP का सीमित उल्लेख है। क्या इन्हें क्रमबद्ध प्रक्रिया-हत्या में शामिल करने का कोई कारण है?


4
यदि आपको वास्तव में किसी प्रक्रिया को मारने के लिए SIGKILL का सहारा लेना है, तो मैं इसे कार्यक्रम का एक बग मानूंगा।
सिगाजाइस

जवाबों:


114

SIGTERM एक एप्लिकेशन को समाप्त करने के लिए कहता है। अन्य संकेत एप्लिकेशन को अन्य चीजों को बताते हैं जो बंद करने के लिए असंबंधित हैं लेकिन कभी-कभी इसका परिणाम समान हो सकता है। उन का उपयोग न करें। यदि आप कोई एप्लिकेशन बंद करना चाहते हैं, तो उसे बताएं। इसे भ्रामक संकेत न दें।

कुछ लोगों का मानना ​​है कि किसी प्रक्रिया को समाप्त करने का स्मार्ट मानक तरीका संकेत के एक बड़े पैमाने पर, जैसे कि HUP, INT, TERM और अंत में KILL भेजकर है। यह मज़ाकीय है। समाप्ति के लिए सही संकेत SIGTERM है और यदि SIGTERM प्रक्रिया को तुरंत समाप्त नहीं करता है, जैसा कि आप पसंद कर सकते हैं, ऐसा इसलिए है क्योंकि आवेदन ने सिग्नल को संभालने के लिए चुना है। जिसका अर्थ है कि इसे तुरंत समाप्त न करने का एक बहुत अच्छा कारण है: इसे करने के लिए सफाई का काम मिला है। यदि आप अन्य संकेतों के साथ उस क्लीनअप कार्य को बाधित करते हैं, तो यह नहीं बता रहा है कि मेमोरी से कौन सा डेटा अभी तक डिस्क पर सहेजा नहीं गया है, क्लाइंट एप्लिकेशन क्या लटका हुआ है या क्या आप इसे "मध्य-वाक्य" में बाधा डाल रहे हैं जो प्रभावी रूप से डेटा भ्रष्टाचार है।

संकेतों का वास्तविक अर्थ क्या है, इस बारे में अधिक जानकारी के लिए, सिगनेशन (2) देखें। "डिफॉल्ट एक्शन" को "विवरण" के साथ भ्रमित न करें, वे समान चीज नहीं हैं।

SIGINT का उपयोग प्रक्रिया के एक इंटरैक्टिव "कीबोर्ड इंटरप्ट" को इंगित करने के लिए किया जाता है। कुछ कार्यक्रम टर्मिनल उपयोगकर्ताओं के उद्देश्य के लिए स्थिति को विशेष तरीके से संभाल सकते हैं।

SIGHUP का उपयोग यह संकेत देने के लिए किया जाता है कि टर्मिनल गायब हो गया है और अब इस प्रक्रिया को नहीं देख रहा है। बस इतना ही। कुछ प्रक्रियाएं प्रतिक्रिया में बंद करने का विकल्प चुनती हैं, आम तौर पर क्योंकि उनका संचालन बिना टर्मिनल के कोई मतलब नहीं रखता है, कुछ अन्य चीजों को करना पसंद करते हैं जैसे कि कॉन्फ़िगरेशन फ़ाइलों को रीचेक करना।

SIGKILL का उपयोग कर्नेल से प्रक्रिया को बलपूर्वक हटाने के लिए किया जाता है। यह इस अर्थ में विशेष है कि यह वास्तव में प्रक्रिया का संकेत नहीं है, बल्कि सीधे कर्नेल द्वारा व्याख्या की जाती है।

SIGKILL न भेजें। स्क्रिप्ट द्वारा निश्चित रूप से कभी नहीं भेजा जाना चाहिए। यदि एप्लिकेशन SIGTERM को संभालता है, तो उसे साफ करने में एक सेकंड लग सकता है, इसमें एक मिनट लग सकता है , एक घंटा लग सकता है । यह इस बात पर निर्भर करता है कि आवेदन को समाप्त होने से पहले क्या करना है। कोई भी तर्क जो किसी एप्लिकेशन के क्लीनअप अनुक्रम को " मानता है " लंबे समय से लिया गया है और एक्स सेकंड के बाद केवल सादे गलत होने पर शॉर्टकट या सिगलीड करने की आवश्यकता है

एकमात्र कारण कि किसी एप्लिकेशन को समाप्त करने के लिए किसी SIGKILL की आवश्यकता होगी , यदि इसके क्लीनअप अनुक्रम के दौरान कुछ खराब हो गया हो। जिस स्थिति में आप एक टर्मिनल खोल सकते हैं और इसे मैन्युअल रूप से खोल सकते हैं। इसके अलावा, केवल एक ही कारण कि आप कुछ और क्यों करेंगे क्योंकि आप इसे खुद को साफ करने से रोकना चाहते हैं

हालांकि 5 सेकंड के बाद भी आधी दुनिया आंख मूंदकर सिगली भेजती है, फिर भी यह बहुत ही गलत है।


13
आप सही कह रहे हैं कि वहां से SIGKILL का बहुत अधिक दुरुपयोग हुआ है। लेकिन एक स्क्रिप्ट से भी, इसे इस्तेमाल करने का समय और स्थान है। कई, कई ऐप SIGTERM को फँसाते हैं और एक सेकंड से भी कम समय में या कुछ ही सेकंड के भीतर इनायत से बाहर निकल जाते हैं, और उनमें से एक अभी भी 30 सेकंड बाद में चल रहा है क्योंकि यह वायर्ड है।
dwc

4
@dwc: एक घंटे के लिए इसे एक बार चलने देने का प्रयास करें। अगर यह नहीं मरता है, तो यह "wedged" है और या तो इसे ठीक करें, या आलसी हो और भविष्य में कुछ समय बाद इसे हटा दें। ध्यान दें कि आप शायद सामान को भ्रष्ट कर रहे हैं और याद रखें कि यह कुछ ऐसा नहीं है जिसे आपको "डिफ़ॉल्ट रूप से" करना चाहिए।
लहनाथ

2
@ ललनाथ: आशा करते हैं कि आपको कोई आपत्ति नहीं है, मैंने उत्तर को अधिक सीधे और स्पष्ट रूप से प्रश्न का अनुसरण करने के लिए आपके पैराग्राफ को फिर से व्यवस्थित किया। SIGKILL रेंट विरोधी अच्छा सामान है, लेकिन एक माध्यमिक बिंदु है। एक उत्कृष्ट और शैक्षिक उत्तर के लिए फिर से धन्यवाद।
सिस्टम PAUSE 21

8
SIGKILL न भेजें। कभी। सिर्फ सादा गलत। वास्तव में? यहां तक ​​कि अगर आपका सिस्टम पहले से ही अनंत छोरों के लिए धन्यवाद जल रहा है। सौभाग्य। -1
konsolebox

//, इसके लिए अपवित्र करना हास्यास्पद है।
नाथन बसानी

17

संक्षिप्त उत्तर : भेजें SIGTERM, 30 सेकंड बाद SIGKILL। यही है, भेजें SIGTERM, थोड़ा इंतजार करें (यह प्रोग्राम से प्रोग्राम में भिन्न हो सकता है, आप अपने सिस्टम को बेहतर जान सकते हैं, लेकिन 5 से 30 सेकंड का समय पर्याप्त है। मशीन को बंद करते समय, आप देख सकते हैं कि यह स्वचालित रूप से 1'30s तक इंतजार कर रहा है। हड़बड़ी क्यों, आखिर?), तो भेजो SIGKILL

उचित जवाब : SIGTERM, SIGINT, SIGKILL यह पर्याप्त से अधिक है। प्रक्रिया बहुत पहले समाप्त हो जाएगी SIGKILL

लांग उत्तर : SIGTERM, SIGINT, SIGQUIT, SIGABRT,SIGKILL

यह अनावश्यक है, लेकिन कम से कम आप अपने संदेश के बारे में प्रक्रिया को भ्रमित नहीं कर रहे हैं। इन सभी संकेतों का मतलब है कि आप चाहते हैं कि यह प्रक्रिया बंद हो जाए और यह बाहर निकले।

कोई फर्क नहीं पड़ता कि आप इस स्पष्टीकरण से क्या जवाब चुनते हैं, इसे ध्यान में रखें!

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

तो, आपको अपने आप को एक प्रोग्रामर के रूप में सोचना चाहिए। क्या आप किसी SIGHUPऐसे प्रोग्राम हैंडलर को कोड करेंगे, जो किसी प्रोग्राम को किसी चीज़ से जोड़ने के लिए कहता है, या आप उसे दोबारा कनेक्ट करने की कोशिश करने के लिए लूप करेंगे? यह यहाँ मुख्य प्रश्न है! इसीलिए सिर्फ संकेत भेजना महत्वपूर्ण है जिसका मतलब है कि आप क्या चाहते हैं।

लगभग बेवकूफ लंबा जवाब :

तालिका के बोल में प्रासंगिक संकेत होते हैं, और यदि प्रोग्राम उन्हें नहीं संभालता है तो डिफ़ॉल्ट क्रियाएं होती हैं।

मैंने उन्हें आदेश दिया था कि मैं उपयोग करने का सुझाव देता हूं (बीटीडब्ल्यू, मैं आपको उचित उत्तर का उपयोग करने का सुझाव देता हूं , यहां यह नहीं), अगर आपको वास्तव में उन सभी की कोशिश करने की आवश्यकता है (यह कहना मजेदार होगा कि तालिका के संदर्भ में आदेश दिया गया है विनाश वे पैदा कर सकते हैं, लेकिन यह पूरी तरह से सच नहीं है)।

तारांकन चिह्न (*) वाले संकेतों की अनुशंसा नहीं की जाती है। इनके बारे में महत्वपूर्ण बात यह है कि आप कभी भी यह नहीं जान सकते हैं कि यह क्या करने के लिए प्रोग्राम किया गया है। विशेष रूप से SIGUSR! यह सर्वनाश शुरू कर सकता है (यह एक प्रोग्रामर के लिए एक नि: शुल्क संकेत है कि वह जो चाहे / वह चाहे!)। लेकिन, अगर संभाला नहीं गया है या असंभावित मामले में इसे समाप्त करने के लिए नियंत्रित किया जाता है, तो कार्यक्रम समाप्त हो जाएगा।

तालिका में, एक मूल डंप को समाप्त करने और उत्पन्न करने के लिए डिफ़ॉल्ट विकल्पों के साथ संकेत अंत में, पहले ही छोड़ दिए जाते हैं SIGKILL

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGTERM      15       Term    Termination signal
SIGINT        2       Term    Famous CONTROL+C interrupt from keyboard
SIGHUP        1       Term    Disconnected terminal or parent died
SIGPIPE      13       Term    Broken pipe
SIGALRM(*)   14       Term    Timer signal from alarm
SIGUSR2(*)   12       Term    User-defined signal 2
SIGUSR1(*)   10       Term    User-defined signal 1
SIGQUIT       3       Core    CONTRL+\ or quit from keyboard
SIGABRT       6       Core    Abort signal from abort(3)
SIGSEGV      11       Core    Invalid memory reference
SIGILL        4       Core    Illegal Instruction
SIGFPE        8       Core    Floating point exception
SIGKILL       9       Term    Kill signal

तब मैं इस बात के लिए सुझाव है कि लगभग बेवकूफ विस्तृत उत्तर है : SIGTERM, SIGINT, SIGHUP, SIGPIPE, SIGQUIT, SIGABRT,SIGKILL

और अंत में, द

निश्चित रूप से लंबा लंबा जवाब :

घर पर यह कोशिश मत करो।

SIGTERM, SIGINT, SIGHUP, SIGPIPE, SIGALRM, SIGUSR2, SIGUSR1, SIGQUIT, SIGABRT, SIGSEGV, SIGILL, SIGFPEऔर कुछ भी नहीं, काम करता है, तो SIGKILL

SIGUSR2इससे पहले SIGUSR1कि हम कार्यक्रम को सिग्नल नहीं संभालते हैं, हम बेहतर होने की कोशिश करें । और SIGUSR1अगर यह उनमें से सिर्फ एक को संभालता है, तो इसे संभालना अधिक संभव है।

BTW, KILL : यह SIGKILLएक प्रक्रिया को भेजने के लिए गलत नहीं है , जैसा कि अन्य उत्तर में कहा गया है। अच्छा, सोचिए जब आप shutdownकमांड भेजते हैं तो क्या होता है ? यह केवल SIGTERMऔर SIGKILLकेवल प्रयास करेगा । आप ऐसा क्यों सोचते हैं? और आपको किसी अन्य सिग्नल की आवश्यकता क्यों है, यदि बहुत ही shutdownकमांड केवल इन दोनों का उपयोग करता है?


अब, लंबे उत्तर पर वापस जाएं , यह एक अच्छा ऑनलाइनर है:

for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done

यह संकेतों के बीच 30 सेकंड के लिए सोता है। आपको एक अन्य की आवश्यकता क्यों होगी ? ;)

इसके अलावा, अनुशंसित: उचित उत्तर15 2 9 से केवल संकेतों के साथ इसे आज़माएं ।

सुरक्षा : echoजब आप जाने के लिए तैयार हों तो दूसरा हटा दें । मैं इसे ऑनलाइनर्स केdry-run लिए कहता हूं । हमेशा परीक्षण करने के लिए इसका उपयोग करें।


स्क्रिप्ट जानलेवा तरीके से

वास्तव में मैं इस सवाल से इतना घबरा गया था कि मैंने एक छोटी सी स्क्रिप्ट बनाने का फैसला किया। कृपया, इसे यहाँ डाउनलोड करने के लिए स्वतंत्र महसूस करें (क्लोन):

GitHub को Killgraceently रिपॉजिटरी से लिंक


8

आमतौर पर आप भेजते हैं SIGTERM, मारने का डिफ़ॉल्ट। यह एक कारण के लिए डिफ़ॉल्ट है। केवल अगर कोई कार्यक्रम उचित समय में बंद नहीं करता है तो आपको इसका सहारा लेना चाहिए SIGKILL। लेकिन ध्यान दें कि SIGKILLकार्यक्रम के साथ अवांछित डेटा को साफ करने की कोई संभावना नहीं है भ्रष्ट हो सकता है।

के रूप में SIGHUP, HUPके लिए खड़ा है "लटका" और ऐतिहासिक रूप से इसका मतलब है कि मॉडेम डिस्कनेक्ट हो गया। यह अनिवार्य रूप से के बराबर है SIGTERM। कारण यह है कि डेमॉन कभी-कभी SIGHUPपुनरारंभ या फिर से लोड कॉन्फ़िगरेशन का उपयोग करते हैं, यह है कि डेमॉन किसी भी नियंत्रित टर्मिनलों से अलग होते हैं क्योंकि डेमॉन को उन की आवश्यकता नहीं होती है और इसलिए उन्हें कभी भी प्राप्त नहीं होगा SIGHUP, इसलिए उस सिग्नल को सामान्य उपयोग के लिए "मुक्त" माना जाता था। सभी डेमॉन पुनः लोड के लिए इसका उपयोग नहीं करते हैं! SIGHUP के लिए डिफ़ॉल्ट कार्रवाई समाप्त करना है और कई डेमन इस तरह से व्यवहार करते हैं! तो आप आँख बंद करके SIGHUPडेमों को भेजने और उनके जीवित रहने की उम्मीद नहीं कर सकते ।

संपादित करें: SIGINT किसी प्रक्रिया को समाप्त करने के लिए संभवतः अनुचित है, क्योंकि यह आम तौर पर ^Cया किसी प्रोग्राम को बाधित करने के लिए टर्मिनल सेटिंग से बंधा हुआ है । कई कार्यक्रम अपने स्वयं के प्रयोजनों के लिए इस पर कब्जा कर लेते हैं, इसलिए यह काम नहीं करने के लिए पर्याप्त सामान्य है। SIGQUITआम तौर पर एक कोर डंप बनाने का डिफ़ॉल्ट होता है, और जब तक आप कोर फाइल नहीं डालना चाहते हैं, यह एक अच्छा उम्मीदवार नहीं है।

सारांश: यदि आप भेजते हैं SIGTERMऔर कार्यक्रम आपके समय सीमा के भीतर नहीं मरता है तो इसे भेजें SIGKILL


4
ध्यान दें कि इसे SIGKILL के साथ पालन करना केवल उन स्थितियों में किया जाना चाहिए जहां डेटा हानि या डेटा भ्रष्टाचार को रोकने की तुलना में तुरंत बंद करना एक उच्च प्राथमिकता है।
thomasrutter

@dwc मुझे आपके उत्तर में निम्न बिंदु समझ नहीं आया। क्या आप कृपया मदद कर सकते हैं "कारण यह है कि डेमॉन कभी-कभी शटअप को पुनः आरंभ करने या पुनः लोड करने के लिए SITEUP का उपयोग करते हैं, यह कि डेमॉन किसी भी नियंत्रित टर्मिनलों से अलग हो जाते हैं और इसलिए कभी भी SIGTERM प्राप्त नहीं करेंगे, इसलिए उस सिग्नल को सामान्य उपयोग के लिए" मुक्त "माना जाता था।"
जैक

3
@ जैक मुझे कोशिश करें: SIGHUP "हैंग अप" सिग्नल है जो एक प्रक्रिया को बताता है कि टर्मिनल डिस्कनेक्ट हो गया। चूंकि डेमॉन पृष्ठभूमि में चलते हैं, उन्हें टर्मिनलों की आवश्यकता नहीं होती है। इसका मतलब है कि "हैंग अप" सिग्नल डेमॉन के लिए प्रासंगिक नहीं है। वे इसे टर्मिनल डिस्कनेक्शन से कभी प्राप्त नहीं करेंगे, क्योंकि उनके पास पहले स्थान पर जुड़े टर्मिनल नहीं हैं। और चूंकि सिग्नल को वैसे भी परिभाषित किया गया है, हालांकि उन्हें मूल उद्देश्य के लिए इसकी आवश्यकता नहीं है, कई डेमॉन इसके लिए एक अलग उद्देश्य के लिए उपयोग करते हैं, जैसे कि उनकी कॉन्फ़िगरेशन फ़ाइलों को फिर से पढ़ना।
प्रणाली PAUSE

धन्यवाद प्रणाली PAUSE यह मददगार है।
जैक

6

SIGTERMवास्तव में एक संदेश भेजने का अर्थ है: " क्या आप इतने दयालु और आत्महत्या करेंगे "। इसे क्लीनअप और शटडाउन कोड चलाने के लिए आवेदन द्वारा फँसाया और संभाला जा सकता है।

SIGKILLआवेदन द्वारा नहीं फँसाया जा सकता। सफाई के लिए बिना किसी अवसर के ओएस द्वारा एप्लिकेशन को मार दिया जाता है।

SIGTERMपहले भेजना , कुछ देर सोना, फिर भेजना ठेठ है SIGKILL


मुझे लगता है कि मतदान सोने से थोड़ा अधिक कुशल होगा (SIGKILL से पहले)
Schneider

@OhadSchneider यह होगा, लेकिन इसके लिए साधारण बैश कमांड से कुछ अधिक की आवश्यकता होगी।
वार्टेक

हाँ, मुझे लगता है कि आपको लूप की आवश्यकता होगी, जबकि प्रक्रिया अभी भी कुछ इस तरह से जीवित है: stackoverflow.com/a/15774758/67824
ओहद श्नाइडर

5
  • SIGTERM एक विंडो में "X" पर क्लिक करने के बराबर है।
  • जब लिनक्स बंद हो रहा हो, तब SIGTERM का उपयोग करता है।

यही मैं जानना चाहता था। +1। धन्यवाद।
ल्यूक

6
"SIGTERM एक विंडो में" X 'को क्लिक करने के बराबर है " नहीं, यह नहीं है, क्योंकि कोई भी एप्लिकेशन आसानी से किसी भी नंबर (दस्तावेज़ और उपकरण, उदाहरण के लिए) विंडो खोल सकता है, अकेले संवाद करने दें, और यह नहीं हो सकता है यहां तक ​​कि एक अंतिम विंडो क्लोज कमांड का जवाब दें क्योंकि यह एक एक्जिट कमांड के लिए है (मैं किसी भी स्पष्ट उदाहरण के बारे में नहीं सोच सकता, लेकिन गैर-स्पष्ट होने के बावजूद, कोई कारण नहीं है कि यह उस तरह से नहीं किया जा सकता है)। SIGTERM है (या होना चाहिए) इनायत करने के लिए आवेदन के समतुल्य समाप्त करने के लिए, हालांकि उस विशेष आवेदन में प्रदर्शन किया जा सकता है
उपयोगकर्ता

3

यहां सभी चर्चा चल रही है, कोई भी कोड प्रस्तावित नहीं किया गया है। यहाँ मेरा ले रहा है:

#!/bin/bash

$pid = 1234

echo "Killing process $pid..."
kill $pid

waitAttempts=30 
for i in $(seq 1 $waitAttempts)
do
    echo "Checking if process is alive (attempt #$i / $waitAttempts)..."
    sleep 1

    if ps -p $pid > /dev/null
    then
        echo "Process $pid is still running"
    else
        echo "Process $pid has shut down successfully"
        break
    fi
done

if ps -p $pid > /dev/null
then
    echo "Could not shut down process $pid gracefully - killing it forcibly..."
    kill -SIGKILL $pid
fi

0

HUP मुझे बकवास लगता है। मैं इसके विन्यास को फिर से पढ़ने के लिए डेमॉन लाने के लिए भेजूँगा।

SIGTERM को इंटरसेप्ट किया जा सकता है; जब यह संकेत प्राप्त होता है तो आपके डेमों में बस क्लीन-अप कोड हो सकता है। आप ऐसा SIGKILL के लिए नहीं कर सकते। इस प्रकार SIGKILL के साथ आप डेमन के लेखक को कोई विकल्प नहीं दे रहे हैं।

विकिपीडिया पर उस पर अधिक

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