सबसे छोटा कोड जो एक डेडलॉक बनाता है


11

गतिरोध बनाने के लिए सबसे छोटा कोड लिखें । कोड निष्पादन रोकना चाहिए, इसलिए यह काम नहीं करता है:

public class DeadlockFail extends Thread{ //Java code
    public static void main(String[]a){
        Thread t = new DeadlockFail();
        t.start();
        t.join();
    }
    //this part is an infinite loop; continues running the loop. 
    public void run(){while(true){}}
}

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


क्या यह एक गतिरोध के रूप में गिना जाता है अगर मैं एक ही धागे से दो बार उसी (गैर-अप्रेंटेंट) को लॉक करने की कोशिश करता हूं? (खेद है कि मुझे सैंडबॉक्स में इस सवाल का एहसास नहीं हुआ)
जॉन ड्वोरक

@JDDvorak क्या ऐसी स्थिति पैदा करता है जहां कोड निष्पादन रुक जाता है क्योंकि एक धागा किसी ऐसी चीज की प्रतीक्षा कर रहा है जो उसे नहीं मिल सकती है (क्योंकि दूसरा इसे पकड़ रहा है और पहले धागे के लिए इंतजार कर रहा है)? या यह एक धागा है? यदि आप एक थ्रेड के साथ ऐसी स्थिति बना सकते हैं, तो यह ठीक है। गतिरोध पर wikepedia लेख पढ़ें, यही मैं उम्मीद करता हूं।
जस्टिन

2
Code execution must haltमुझे समझ नहीं आ रहा है। यदि यह रुक गया तो यह कैसा गतिरोध है? क्या आपका मतलब है कि यह गधे की तरह घूमने की बजाय किसी चीज़ का इंतज़ार कर रहा होगा?
Cruncher

@ क्रंचर उदाहरण पर एक नज़र डालें जो काम नहीं करता है। कोड निष्पादन बंद नहीं होता है क्योंकि लूप चालू रहता है। हां मेरा मतलब है कि कताई के बजाय इंतजार करना।
जस्टिन

तो अगर आप Dyalog APL में खुद के लिए UI थ्रेड बना सकते हैं, तो क्या इसका मतलब यह है कि जावास्क्रिप्ट उत्तर पाने की कुछ उम्मीद है? हालांकि मुझे संदेह है कि इस तरह की सोच से इस उत्तर का द्वार खुल जाएगा: जावास्क्रिप्ट 6 "प्रतीक्षा ()" ... ermmm। नहीं। संबंधित: क्या थ्रेड के लिए संभव है डेडलॉक ही?
नाथन कूपर

जवाबों:


11

दिल्लोग एपीएल (10)

⎕TSYNC⎕TID

⎕TSYNCदिए गए धागे के समाप्त होने तक धागा प्रतीक्षा ⎕TIDकरता है, वर्तमान धागा देता है।

Dyalog APL गतिरोधों को पहचान सकता है, इसलिए यह तुरंत प्रतिक्रिया करता है

DEADLOCK

मज़े की बात यह है कि, आपको किसी भी अतिरिक्त थ्रेड को स्पैन करने की भी आवश्यकता नहीं है, जिससे यूआई थ्रेड का इंतजार काफी हो जाता है।

यदि यह धोखा है और नए धागे वास्तव में आवश्यक हैं, तो आप इसे 27 वर्णों में कर सकते हैं:

{∇⎕TSYNC&{⎕TSYNC⎕TID+1}&0}0

F & xFमूल्य पर एक नए थ्रेड में चलता है x, और थ्रेड आईडी लौटाता है। इसलिए:

  • {⎕TSYNC⎕TID+1}&0 एक थ्रेड बनाता है जो उस थ्रेड के साथ सिंक्रोनाइज़ करेगा जिसकी आईडी अपने आप से अधिक है,
  • ⎕TSYNC& एक नया थ्रेड बनाता है जो पिछले थ्रेड के साथ सिंक्रोनाइज़ करेगा, और जिसे उस थ्रेड की तुलना में एक आईडी अधिक मिलती है जो अभी बनाया गया था (यह मानते हुए कि कुछ और नहीं थ्रेड बना रहा है)।
  • एक अनंत लूप का कारण बनता है (इसलिए हम थ्रेड बनाते रहते हैं जब तक कि कोई गतिरोध न हो)।

जैसे ही दूसरा धागा बनने से पहले यह गतिरोध होगा, इससे पहले कि कोई दौड़ना शुरू करे, जो बहुत जल्द हो:

9:DEADLOCK

2 बाइट्स बचाएं: ⎕TSYNC 0'. ⎕TID` है 0
आदम

8

जाओ, ४२

package main
func main(){<-make(chan int)}

माफी, downvoter, यह कैसे काम करता है प्रदान करने के लिए नहीं। यह एक अनाम चैनल का निर्माण करता है और उसमें से पढ़ता है। यह मुख्य धागे को तब तक रोकता है जब तक कि कोई मूल्य चैनल को नीचे नहीं भेजा जाता है, जो स्पष्ट रूप से कभी नहीं होता है क्योंकि कोई अन्य थ्रेड सक्रिय नहीं होते हैं, और इस प्रकार, गतिरोध।


2
यह कैसे काम करता है?
जस्टिन

4

रूबी, 39 अक्षर

T=Thread;t=T.current;T.new{t.join}.join

जोहानस कुह्न के जावा जवाब से बेशर्मी से चुराए गए क्रॉस-जॉइन का उपयोग करने का विचार

यदि हम किसी विशिष्ट वातावरण में कोड को ट्यून करते हैं तो हम चार वर्णों ( 35 तक ) को शेव कर सकते हैं। JRuby का कंसोल IRB सिंगल-थ्रेडेड है:

T=Thread;T.new{T.list[0].join}.join


यह मेरा पिछला समाधान है:

म्यूटेक्स पर एक धागा फंसना आसान है:

m=Mutex.new;2.times{Thread.new{m.lock}}

लेकिन यह एक उचित गतिरोध नहीं है, क्योंकि दूसरा धागा तकनीकी रूप से पहले धागे की प्रतीक्षा नहीं कर रहा है। विकिपीडिया के अनुसार गतिरोध के लिए "पकड़ और प्रतीक्षा" एक परिमेय स्थिति है। पहला धागा प्रतीक्षा नहीं करता है, और दूसरा धागा कुछ भी पकड़ में नहीं आता है।

माणिक, 97 95 अक्षर

m,n=Mutex.new,Mutex.new
2.times{o,p=(m,n=n,m)
Thread.new{loop{o.synchronize{p.synchronize{}}}}}

यह एक क्लासिक गतिरोध है। दो सूत्र दो संसाधनों के लिए प्रतिस्पर्धा करते हैं, अगर वे सफल होते हैं तो फिर से प्रयास करते हैं। आम तौर पर वे मेरी मशीन पर एक सेकंड के भीतर फंस जाते हैं।

लेकिन, यदि असीम रूप से कई थ्रेड्स (जिनमें से कोई भी सीपीयू असीम रूप से खपत करता है और जिनमें से कुछ गतिरोध है) ठीक है,

माणिक, 87 85 अक्षर

m,n=Mutex.new,Mutex.new
loop{o,p=(m,n=n,m)
Thread.new{o.synchronize{p.synchronize{}}}}

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


आपको अतिरिक्त oऔर pचरों की आवश्यकता क्यों है ? क्या आप बस पास नहीं कर सकते mऔर nनए थ्रेड के लिए?
जोहान्स कुह्न

@JohannesKuhn mऔर nवैश्विक हैं। दोनों सूत्र उन्हें एक ही क्रम में देखते हैं। oऔर pथ्रेड-लोकल (लूप पुनरावृत्ति के लिए स्कूप्ड) हैं। उपयोग t[...]करना शायद महंगा हो जाएगा, और मैं बंद करने की तुलना में धागे को मापदंडों को पारित करने का कोई बेहतर तरीका नहीं देख सकता हूं। newकोड को दो वर्णों से लंबा करने के लिए अतिरिक्त पैरामीटर जोड़ना ।
जॉन ड्वोरक

@JohannesKuhn मुझे आशा है कि आपको कोई आपत्ति नहीं है मैंने आपके कुछ तर्क उधार लिए हैं
जॉन ड्वोरक

मुझे कोई आपत्ति नहीं है। बहुत बढ़िया।
जोहान्स कुह्न

यदि हम मान लें कि हम मुख्य सूत्र में हैं, तो हम इसे 32 वर्णों तक T=Thread;T.new{T.main.join}.join
घटा सकते हैं


4

बैश + जीएनयू कोरुटिल्स, 11 बाइट्स

mkfifo x;<x

एक भटका FIFO बनाता है xवर्तमान निर्देशिका में (इसलिए आपको उस नाम से फ़ाइल की आवश्यकता नहीं होगी)। एफआईएफओ को नियमित फाइलों की तरह ही हटाया जा सकता है, इसलिए इसे साफ करना मुश्किल नहीं होना चाहिए।

एक FIFO में एक राइट साइड और एक रीड साइड होता है; एक ब्लॉक को खोलने का प्रयास तब तक किया जाता है जब तक कि दूसरी प्रक्रिया दूसरे को नहीं खोलती है, और ऐसा लगता है कि जानबूझकर एक सिंक्रनाइज़ेशन आदिम के रूप में डिजाइन किया गया है। यह देखते हुए कि यहां केवल एक धागा है, जैसे ही हम इसे खोलने की कोशिश करते हैं<x , हम अटक जाते हैं। (आप किसी अन्य प्रक्रिया से प्रश्न में FIFO को लिखने के माध्यम से गतिरोध को कम कर सकते हैं।)

यह एक अलग तरह का गतिरोध होता है जब दो संसाधन होते हैं, और दो धागे एक होते हैं और दूसरे की आवश्यकता होती है; बल्कि, इस मामले में, शून्य संसाधन हैं और प्रक्रिया को एक की आवश्यकता है। अन्य उत्तरों के आधार पर, मुझे लगता है कि यह मायने रखता है, लेकिन मैं समझ सकता हूं कि एक डेडलॉक शुद्धतावादी कैसे उत्तर को अस्वीकार करना चाहता है।

यह सोचने के लिए आओ, मैं वास्तव में तीन गतिरोध जैसी स्थितियों के बारे में सोच सकता हूं:

  1. "पारंपरिक" गतिरोध: दो धागे प्रत्येक लॉक जारी होने की प्रतीक्षा कर रहे हैं, जो दूसरे धागे द्वारा आयोजित किया जाता है।

  2. एक एकल थ्रेड लॉक के रिलीज़ होने की प्रतीक्षा कर रहा है, लेकिन यह लॉक को स्वयं रखता है (और इस प्रकार इसे रिलीज़ करने में सक्षम होने से रोक रहा है)।

  3. एक एकल थ्रेड एक सिंक्रोनाइज़ेशन प्राइमैटिव के रिलीज़ होने की प्रतीक्षा कर रहा है, लेकिन एक स्वाभाविक रूप से लॉक अवस्था में सिंक्रोनाइज़ेशन प्राइमेटिव शुरू होता है और इसे बाहरी रूप से अनलॉक करना पड़ता है, और ऐसा करने के लिए कुछ भी प्रोग्राम नहीं किया गया है।

यह टाइप 3 का एक गतिरोध है, जो एक तरह से अन्य दो से मौलिक रूप से अलग है: आप सिद्धांत रूप में, प्रश्न में सिंक्रनाइज़ेशन आदिम अनलॉक करने के लिए एक प्रोग्राम लिख सकते हैं, फिर इसे चलाएं। उस ने कहा, यह प्रकार 1 और 2 के गतिरोधों पर लागू होता है, यह देखते हुए कि कई भाषाएं आपको एक लॉक जारी करने की अनुमति देती हैं जो आपके पास नहीं हैं (आप इसे नहीं मानते हैं करने के लिए है और यदि आप के लिए एक कारण नहीं था ऐसा करने के लिए कोई कारण नहीं होता पहली बार में ताले का उपयोग करें, लेकिन यह काम करता है ...)। इसके अलावा, यह एक कार्यक्रम पर विचार करने के लायक हैmkfifo x;<x;echo test>x ; यह प्रोग्राम का प्रकार 2 गतिरोध के विपरीत है (यह) FIFO के दोनों सिरों को खोलने की कोशिश कर रहा है, लेकिन यह एक छोर को तब तक नहीं खोल सकता है जब तक कि यह दूसरे छोर को नहीं खोलता है), लेकिन इसे इस एक से अतिरिक्त कोड जोड़कर बनाया गया था जो इस एक के बाद कभी नहीं चलता! मुझे लगता है कि समस्या यह है कि ताला लॉक किया गया है या नहीं यह इरादा पर निर्भर करता है लॉक के उपयोग के पीछे, इसलिए इसे निष्पक्ष रूप से परिभाषित करना मुश्किल है (विशेषकर इस तरह के मामले में जहां लॉक का एकमात्र उद्देश्य जानबूझकर गतिरोध उत्पन्न करना है)।



2

ग्लिबैक के साथ बैश, 6 बाइट्स

एक पुराने धागे को पुनर्जीवित करने के लिए क्षमा करें, लेकिन विरोध नहीं कर सका।

जड़ के रूप में:

pldd 1

से आदमी pldd :

BUGS के
बाद से glibc 2.19, pldd टूट गया है: यह बस फांसी होने पर लटका देता है। यह स्पष्ट नहीं है कि क्या यह कभी तय होगा।


जब तक मूल समय संवेदनशील नहीं था तब तक एक पुराने चलने पर जवाब देने में कोई समस्या नहीं है।
तदर्थ गार्फ हंटर

2

जावा, 191

class B extends Thread{public static void main(String[]a)throws Exception{new B().join();}Thread d;B(){d=Thread.currentThread();start();}public void run(){try{d.join();}catch(Exception e){}}}

Ungolfed:

class B extends Thread {
    Thread d;
    public static void main(String[] args) throws Exception {
        new B().join();
    }
    B() { // constructor
        d = Thread.currentThread();
        start();
    }
    public void run() {
        try {
            d.join();
        } catch (Exception e) {
        }
    }
}

एक नया थ्रेड प्रारंभ करता है और उस joinपर (यह धागा समाप्त होने तक प्रतीक्षा करें), जबकि नया थ्रेड मूल थ्रेड के साथ ऐसा ही करता है।


क्या आप इसे फेंकने और पकड़ने के Errorबजाय कम कर सकते हैं Exception?
mbomb007

नहीं। Thread.join()फेंकता है InteruptedException, जो उप का नहीं है Error
जोहान्स कुह्न

2

Tcl, 76

package r Thread;thread::send [thread::create] "thread::send [thread::id] a"

गतिरोध।

यह एक नया थ्रेड बनाता है, और दूसरे थ्रेड को मेरे थ्रेड को संदेश भेजने के लिए कहता है (निष्पादित करने के लिए स्क्रिप्ट)।

लेकिन दूसरे थ्रेड को एक संदेश भेजना आमतौर पर तब तक ब्लॉक होता है जब तक स्क्रिप्ट निष्पादित नहीं हो जाती। और जब यह अवरुद्ध होता है, तो कोई भी संदेश संसाधित नहीं होता है, इसलिए दोनों थ्रेड अपने संदेश को संसाधित करने के लिए दूसरे की प्रतीक्षा करते हैं।


यह कैसे काम करता है?
जॉन ड्वोरक

thread::sendएक स्क्रिप्ट को कतारबद्ध करता है जिसे दूसरे धागे में निष्पादित किया जाना चाहिए और इसके पूरा होने की प्रतीक्षा करें। तो अंत में हमारे पास थ्रेड 2 के लिए थ्रेड 1 है, और थ्रेड 2 थ्रेड के लिए प्रतीक्षा कर रहा है 1.
जोहान्स कुह्न

1

मॉनिटर-गाली के साथ वैकल्पिक जावा (248 चरस)

class A{public static void main(String args[]) throws Exception{final String a="",b="";new Thread(new Runnable(){public void run(){try {synchronized(b){b.wait();}} catch (Exception e) {}a.notify();}}).start();synchronized(a){a.wait();}b.notify();}}

1

स्काला, 104 बाइट्स

class A{s=>lazy val x={val t=new Thread{override def run{s.synchronized{}}};t.start;t.join;1}};new A().x

आलसी वैल आरंभीकरण ब्लॉक एक शर्त पूरी होने तक निलंबित करता है। इस शर्त को केवल आलसी वैल एक्स के मूल्य को पढ़कर पूरा किया जा सकता है - इस स्थिति को पूरा करने वाला एक और धागा ऐसा नहीं कर सकता है। इस प्रकार, एक परिपत्र निर्भरता का गठन होता है, और आलसी वैल को आरंभीकृत नहीं किया जा सकता है।


यह कैसे काम करता है?
Addison Crump

मैंने एक स्पष्टीकरण जोड़ा।
मार्टिन सीलर

1

कोटलिन, 35/37/55 बाइट्स

सामान्य विषय: Thread.currentThread().join()

जेवीएम बग्स / बहुत विशिष्ट कोड को इस सबमिशन के खिलाफ छोड़कर यह शॉड कभी भी वापस नहीं आता है क्योंकि वर्तमान निष्पादन धागा अब निष्क्रिय हो गया है जो खुद मरने का इंतजार कर रहा है।


बुराई संपत्ति: 35 बाइट्स (गैर-प्रतिस्पर्धात्मक): 35 बाइट्स

val a=Thread.currentThread().join()

इसे कहीं भी घोषित करना एक संपत्ति घोषणा वैध है जो भी इसे आरम्भ कर रहा है वह गतिरोध करेगा। एक शीर्ष-स्तरीय संपत्ति के मामले में, उस फ़ाइल के लिए मैप की गई JVM वर्ग को इनिशियलाइज़ करने वाला क्लास लोडर होगा (डिफ़ॉल्ट रूप से)[file name]Kt.class )।

गैर-प्रतिस्पर्धात्मक क्योंकि "इसे शीर्ष स्तर की संपत्ति के रूप में कहीं भी रखा जाए" प्रतिबंधात्मक है।


समारोह: 37 बाइट्स

fun a()=Thread.currentThread().join()


मुख्य (): 55 बाइट्स

fun main(a:Array<String>)=Thread.currentThread().join()


1

पावरशेल, 36 28 23 बाइट्स

gps|%{$_.waitforexit()}

स्व गतिरोध। हम सभी प्रक्रियाओं को प्राप्त करते हैं Get-Processऔर फिर उनमें से प्रत्येक के बाहर निकलने के लिए धैर्यपूर्वक प्रतीक्षा करते हैं ... जो कि लगभग कभी नहीं होगा, क्योंकि प्रक्रिया स्वयं ही प्रतीक्षा कर रही होगी।

संपादित - सहेजे गए 5 बाइट रोमन ग्रैफ़ के लिए धन्यवाद


(gps)|%{$_.waitforexit()} तीन बाइट्स छोटा है और सभी प्रक्रियाओं से बाहर निकलने का इंतजार करता है।
रोमन ग्रैफ

@ RomanGräf वास्तव में, लेकिन gpsउस मामले में परिंदों की जरूरत नहीं है , इसलिए कुल 5 बाइट्स बचाए गए।
AdmBorkBork

0

सी (केवल लिनक्स), 31 बाइट्स - इसे ऑनलाइन आज़माएं!

main(a){syscall(240,&a,0,a,0);}

सिस्टम कॉल 240 (0xf0) फ्यूटेक्स (2) , या तेज उपयोगकर्तास्पेस म्यूटेक्स है। दस्तावेज़ीकरण में कहा गया है कि पहला तर्क फ़ुटेक्स का एक संकेतक है, दूसरा तर्क ऑपरेशन है (0 का अर्थ है FUTEX_WAIT, अर्थात, जब तक कि कोई अन्य फ़ुटेक्स अनलॉक नहीं होता है) प्रतीक्षा करें। तीसरा तर्क वह मान है जिसकी उम्मीद आप अभी भी बंद किए जाने के समय फ्यूटेक्स से करते हैं, और चौथा टाइमआउट का सूचक होता है (NULL फॉर नो टाइमआउट)।

जाहिर है, चूंकि फ्यूटेक्स को अनलॉक करने के लिए कोई अन्य धागा नहीं है, इसलिए यह हमेशा के लिए स्वयं-गतिरोध में इंतजार करेगा। यह सत्यापित किया जा सकता है (के माध्यम से topया अन्य कार्य प्रबंधक) कि प्रक्रिया कोई सीपीयू समय का उपयोग करता है, जैसा कि हमें एक डेडलॉक थ्रेड से उम्मीद करनी चाहिए।


0

जूलिया 0.6 , 13 बाइट्स

प्रश्न की तुलना में भाषा नई। एक कार्य पर प्रतीक्षा करें (जैसे एक गो-दिनचर्या, वर्तमान में एक ही धागे पर होगा, जूलिया के भविष्य के संस्करणों में यह एक और धागे पर हो सकता है) जो चलाने के लिए निर्धारित नहीं है।

wait(@task +)

इसे ऑनलाइन आज़माएं!


0

वनस्पति विज्ञान, 3x3 = 9 (9 बाइट्स)

v
lCv
> <

चरण 5 दो बॉट्स के साथ अनिश्चित काल तक एक-दूसरे को स्थानांतरित करने के लिए इंतजार कर रहा है ... एक बॉट आगे नहीं बढ़ सकता है क्योंकि यह दूसरे के लिए नीचे दाएं वर्ग से बाहर जाने की प्रतीक्षा कर रहा है, और दूसरा बॉट नहीं चल सकता क्योंकि यह इंतजार कर रहा है पहले बॉट नीचे केंद्र वर्ग से बाहर जाने के लिए।


0

वाटरफॉल मॉडल (Ratiofall), 13 बाइट्स

[[2,1],[1,1]]

इसे ऑनलाइन आज़माएं!

यहाँ एक मजेदार ऑफ-द-वॉल जवाब है। यह वाटरफॉल मॉडल में सबसे सरल संभव अनंत लूप है (वाटरफॉल मॉडल में चर जब भी और कभी भी हो रहा होता है, तो यह प्रोग्राम एक चर को परिभाषित करता है जो जब भी घटता है तब खुद ही बढ़ जाता है, इसलिए ऐसा कोई तरीका नहीं है जो कभी भी हो सकता है)।

प्रश्न एक गतिरोध के लिए पूछता है, एक अनंत लूप नहीं। हालांकि, हम विशिष्ट कार्यान्वयन के व्यवहार का फायदा उठा सकते हैं। अनुकूलन स्तर 2 या उच्चतर पर (डिफ़ॉल्ट 3 है), दुभाषिया Ratiofall अनंत लूप का पता लगाएगा, और इसे गतिरोध में अनुकूलित करेगा ...! इसलिए कम से कम अगर हम भाषाओं को उनके कार्यान्वयन से परिभाषित करते हैं (जो आमतौर पर इस साइट पर मामला है), यह कार्यक्रम वास्तव में एक गतिरोध को परिभाषित करता है, बजाय एक अनंत लूप के।

आप इसे ऑनलाइन आज़माएं समय रिपोर्ट से गतिरोध के सबूत देख सकते हैं! ऊपर लिंक:

Real time: 60.004 s
User time: 0.006 s
Sys. time: 0.003 s
CPU share: 0.01 %
Exit code: 124

कार्यक्रम 60 सेकंड तक चला (जब तक कि TIO ने इसे स्वचालित रूप से समाप्त नहीं कर दिया), लेकिन उस समय के अधिकांश के लिए, कोई CPU उपयोग नहीं था, प्रोग्राम चलने में कोई समय व्यतीत नहीं हुआ, और प्रोग्राम की ओर से कर्नेल द्वारा कोई समय व्यतीत नहीं किया गया।

और भी मजबूत सबूत पाने के लिए, आप सिस्टम-कॉल-लेवल डीबगर जैसे रतिफ़ॉल को चला सकते हैं strace; लिनक्स पर ऐसा करने से इंटरप्रिटर को एक futexसिस्टम कॉल पर ब्लॉकिंग दिखाई देगी जो लॉक लेने का प्रयास करती है जो कभी भी रिलीज़ नहीं होगी।


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