मुझे अपने pthreads में से किसी एक में टाइमआउट स्थापित करने में समस्या हो रही है। मैंने यहां अपना कोड सरल कर दिया है और मैंने थ्रेड में चल रहे सीएनएफ एल्गोरिदम होने के लिए इस मुद्दे को अलग कर दिया है।

int main(){
  pthread_t t1;
  pthread_t t2;
  pthread_t t3; //Running multiple threads, the others work fine and do not require a timeout.

  pthread_create(&t1, nullptr, thread1, &args);
  pthread_join(t1, nullptr);

  std::cout << "Thread should exit and print this\n"; //This line never prints since from what I've figured to be a lack of cancellation points in the actual function running in the thread.

  return  0;
}

void* to(void* args) {
    int timeout{120};
    int count{0};
    while(count < timeout){
        sleep(1);
        count++;
    }
    std::cout << "Killing main thread" << std::endl;
    pthread_cancel(*(pthread_t *)args);
}

void *thread1 (void *arguments){
  //Create the timeout thread within the CNF thread to wait 2 minutes and then exit this whole thread
  pthread_t time;
  pthread_t cnf = pthread_self();
  pthread_create(&time, nullptr, &timeout, &cnf);

  //This part runs and prints that the thread has started
  std::cout << "CNF running\n"; 
  auto *args = (struct thread_args *) arguments;

  int start = args->vertices;
  int end = 1;

  while (start >= end) {
     //This is where the issue lies 
     cover = find_vertex_cover(args->vertices, start, args->edges_a, args->edges_b); 

    start--;
  }

  pthread_cancel(time); //If the algorithm executes in the required time then the timeout is not needed and that thread is cancelled. 
  std::cout << "CNF END\n";
  return nullptr;
}

मैंने find_vertex_cover फ़ंक्शन पर टिप्पणी करने और infinite loop जोड़ने की कोशिश की और मैं एक timeout बनाने और इस तरह से थ्रेड को समाप्त करने में सक्षम था। फ़ंक्शन वास्तव में ठीक उसी तरह काम कर रहा है जैसे इसे करना चाहिए। जिन परिस्थितियों में मैं इसे चला रहा हूं, उसके तहत इसे चलाने में हमेशा के लिए लगना चाहिए और इसलिए मुझे एक टाइमआउट चाहिए।

//This was a test thread function that I used to validate that implementing the timeout using `pthread_cancel()` this way works. The thread will exit once the timeout is reached.

void *thread1 (void *args) {
    pthread_t x1;
    pthread_t x2 = pthread_self();
    pthread_create(&x1, nullptr, to, &x2);

    /*
    for (int i = 0;i<100; i++){
        sleep(1);
        std::cout << i << std::endl;
    }
    */
}

इस फ़ंक्शन का उपयोग करके मैं यह सत्यापित करने में सक्षम था कि मेरा टाइमआउट थ्रेड दृष्टिकोण काम करता है। मुद्दा यह है कि जब मैं वास्तव में सीएनएफ एल्गोरिथम (हुड के नीचे मिनीसैट का उपयोग करके) चलाता हूं, एक बार find_vertex_cover चलता है, तो थ्रेड को समाप्त करने का कोई तरीका नहीं है। जिस स्थिति में मैं कार्यान्वित कर रहा हूं उसमें एल्गोरिदम विफल होने की उम्मीद है, यही कारण है कि एक टाइमआउट लागू किया जा रहा है।

मैंने pthread_cancel() का उपयोग करने के बारे में पढ़ा है और जबकि यह एक शानदार तरीका नहीं है, यह एकमात्र तरीका है जिससे मैं टाइमआउट लागू कर सकता हूं।

इस मुद्दे पर किसी भी मदद की सराहना की जाएगी।

1
ibby 11 अप्रैल 2020, 10:59

1 उत्तर

सबसे बढ़िया उत्तर

मैंने pthread_cancel() का उपयोग करने के बारे में पढ़ा है और यह एक शानदार तरीका नहीं है [..]

ये सही है। pthread_cancel से बचना चाहिए। यह विशेष रूप से C++ में उपयोग के लिए खराब है क्योंकि यह अपवाद प्रबंधन के साथ असंगत है। आपको std::thread का उपयोग करना चाहिए और थ्रेड समाप्ति के लिए, आप संभवतः सशर्त चर या एक परमाणु चर का उपयोग कर सकते हैं जो सेट होने पर "अनंत लूप" को समाप्त करता है।

इसके अलावा, pthread_cancel के माध्यम से रद्द करना दो बातों पर निर्भर करता है: १) रद्दीकरण स्थिति २) रद्दीकरण प्रकार।

डिफ़ॉल्ट रद्दीकरण स्थिति सक्षम है। लेकिन डिफ़ॉल्ट रद्दीकरण प्रकार स्थगित है - जिसका अर्थ है कि रद्दीकरण अनुरोध केवल अगले रद्दीकरण बिंदु पर दिया जाएगा। मुझे संदेह है कि find_vertex_cover में कोई रद्दीकरण बिंदु है। तो आप कॉल के माध्यम से रद्दीकरण प्रकार को asynchronous पर सेट कर सकते हैं:

pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

धागे से आप तुरंत रद्द करने में सक्षम होना चाहते हैं।

लेकिन फिर से, मेरा सुझाव है कि pthread_cancel दृष्टिकोण बिल्कुल न लें और इसके बजाय "रद्द करें" तर्क को फिर से लिखें ताकि इसमें pthread_cancel शामिल न हो।

1
P.P 11 अप्रैल 2020, 13:23