Pthread_create () द्वारा कहे जाने वाले कार्य के लिए कई तर्क?


93

मुझे एक फ़ंक्शन के लिए कई तर्क पास करने की आवश्यकता है जिसे मैं एक अलग थ्रेड पर कॉल करना चाहूंगा। मैंने पढ़ा है कि ऐसा करने का विशिष्ट तरीका एक संरचना को परिभाषित करना है, फ़ंक्शन को उस के लिए एक पॉइंटर पास करना है, और तर्कों के लिए इसे संक्षिप्त करना है। हालाँकि, मैं यह काम करने में असमर्थ हूँ:

#include <stdio.h>
#include <pthread.h>

struct arg_struct {
    int arg1;
    int arg2;
};

void *print_the_arguments(void *arguments)
{
    struct arg_struct *args = (struct arg_struct *)args;
    printf("%d\n", args -> arg1);
    printf("%d\n", args -> arg2);
    pthread_exit(NULL);
    return NULL;
}

int main()
{
    pthread_t some_thread;
    struct arg_struct args;
    args.arg1 = 5;
    args.arg2 = 7;

    if (pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0) {
        printf("Uh-oh!\n");
        return -1;
    }

    return pthread_join(some_thread, NULL); /* Wait until thread is finished */
}

इसके लिए आउटपुट होना चाहिए:

5
7

लेकिन जब मैं इसे चलाता हूं तो मुझे वास्तव में मिलता है:

141921115
-1947974263

किसी को पता है कि मैं क्या गलत कर रहा हूँ?


2
यह ढेर पर आवंटित करने का प्रयास करें?
कार्सन मायर्स

1
@ करसन को इससे फर्क क्यों पड़ना चाहिए?
सिगाजिस

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

@ सी कमोडोर जेगर ओह! धन्यवाद, यही वह समस्या है जिसके साथ मैं काम कर रहा था। जैसा कि कार्सन ने कहा, मैंने इसे मॉलोक () का उपयोग करके ढेर पर आवंटित करके तय किया। यह अब बहुत अधिक समझ में आता है।
माइकल

जवाबों:


77

क्योंकि तुमने कहा

struct arg_struct *args = (struct arg_struct *)args;

के बजाय

struct arg_struct *args = arguments;


4
@sigjuice, यह मेरे लिए काम नहीं करता है। मुझे संकलन त्रुटि दिखाई देती है: अमान्य रूपांतरण 'शून्य *' से 'arg_struct *' तक।
निश्ता


4

main()इसका स्वयं का धागा और स्टैक चर है। या तो ढेर में 'आर्ग' के लिए मेमोरी आवंटित करें या इसे वैश्विक बनाएं:

struct arg_struct {
    int arg1;
    int arg2;
}args;

//declares args as global out of main()

फिर निश्चित रूप से संदर्भों args->arg1को args.arg1आदि से बदल दें ।


2

उपयोग:

struct arg_struct *args = malloc(sizeof(struct arg_struct));

और इस तरह इस तर्क को पारित करें:

pthread_create(&tr, NULL, print_the_arguments, (void *)args);

मुक्त args मत भूलना! ;)


1

Print_the_arguments का तर्क तर्क है, इसलिए आपको इसका उपयोग करना चाहिए:

struct arg_struct *args = (struct arg_struct *)arguments. 

1
struct arg_struct *args = (struct arg_struct *)args;

-> यह असाइनमेंट गलत है, मेरा मतलब है कि इस संदर्भ में वेरिएबल तर्क का उपयोग किया जाना चाहिए। चीयर्स !!!


1

इस कोड के थ्रेड निर्माण में, फ़ंक्शन पॉइंटर का पता पारित किया जा रहा है। असली pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0

इसे के रूप में पढ़ना चाहिए pthread_create(&some_thread, NULL, print_the_arguments, (void *) &args)

याद रखने का एक अच्छा तरीका यह है कि इस फ़ंक्शन के सभी तर्कों को संबोधित किया जाना चाहिए।

some_threadको वैधानिक रूप से घोषित किया जाता है, इसलिए पते का उपयोग करके ठीक से भेजा जाता है &

मैं एक pthread_attr_tचर बनाऊंगा, फिर उस pthread_attr_init()पर प्रयोग करूंगा और उस चर का पता पास करूंगा । लेकिन, एक NULLपॉइंटर पास करना भी मान्य है।

&समारोह लेबल के सामने क्या समस्या यहां खड़ी कर रहा है है। उपयोग किया गया लेबल पहले से ही एक void*फ़ंक्शन के लिए है, इसलिए केवल लेबल आवश्यक है।

!= 0अंतिम तर्क के साथ कहना अनिर्धारित व्यवहार का कारण होगा। इसे जोड़ने का मतलब है कि एक संदर्भ के बजाय एक बूलियन पारित किया जा रहा है।

आकाश अग्रवाल का जवाब भी इस कोड की समस्या के समाधान का हिस्सा है।


1

मैं मूल पोस्टर, माइकल के रूप में एक ही सवाल है।

हालांकि मैंने सफलता के बिना मूल कोड के लिए प्रस्तुत उत्तरों को लागू करने की कोशिश की है

कुछ परीक्षण और त्रुटि के बाद, यहां कोड का मेरा संस्करण है जो काम करता है (या कम से कम मेरे लिए काम करता है!)। और यदि आप बारीकी से देखते हैं, तो आप ध्यान देंगे कि यह पहले के पोस्ट किए गए समाधानों के लिए अलग है।

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

struct arg_struct
{
   int arg1;
   int arg2;
} *args;

void *print_the_arguments(void *arguments)
{
   struct arg_struct *args = arguments;
   printf("Thread\n");
   printf("%d\n", args->arg1);
   printf("%d\n", args->arg2);
   pthread_exit(NULL);
   return NULL;
}

int main()
{
   pthread_t some_thread;
   args = malloc(sizeof(struct arg_struct) * 1);

   args->arg1 = 5;
   args->arg2 = 7;

   printf("Before\n");
   printf("%d\n", args->arg1);
   printf("%d\n", args->arg2);
   printf("\n");


   if (pthread_create(&some_thread, NULL, &print_the_arguments, args) != 0)
   {
      printf("Uh-oh!\n");
      return -1;
   }

   return pthread_join(some_thread, NULL); /* Wait until thread is finished */
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.