Pthread_create () দ্বারা ডাকা একাধিক যুক্তি?


96

আমাকে একটি ফাংশনে একাধিক যুক্তি পাস করতে হবে যা আমি একটি পৃথক থ্রেডে কল করতে চাই। আমি পড়েছি যে এটি করার সাধারণ উপায় হ'ল একটি স্ট্রাক্টকে সংজ্ঞায়িত করা, ফাংশনটিকে একটি পয়েন্টারটি পাস করা এবং আর্গুমেন্টগুলির জন্য এটির বিন্যাস করা। যাইহোক, আমি এটি কাজ করতে অক্ষম:

#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

আমি কি ভুল করছি কেউ জানেন?


4
এটি গাদা উপর বরাদ্দ চেষ্টা?
কারসন মায়ার্স

4
@ কারসন এই যে একটি পার্থক্য করা উচিত?
সিগজুইস

4
আপনার কাঠামো কমপক্ষে আপনার থ্রেডের মতো দীর্ঘস্থায়ী হওয়া উচিত। যদি আপনি একটি থ্রেড তৈরি করেন এবং ফাংশন থেকে ফিরে আসেন যাকে pthread_create () বলা হয়, স্ট্যাকের উপর বরাদ্দকৃত কাঠামো অন্য ডেটা দ্বারা ওভাররাইট হয়ে যেতে পারে এবং আপনার থ্রেড ফাংশনে সমস্যা দেখা দিতে পারে। এই উদাহরণস্বরূপ, এটি কোনও সমস্যা নয়, যেহেতু তৈরি থ্রেডটি শ্রমিক ফেরার আগে থ্রেডটি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করে।
কমডোর জায়েজার

কমডোর জায়েগার ওহ! আপনাকে ধন্যবাদ, আমি যে অন্যটির সাথে কাজ করছি তার সাথেই আমার সমস্যাটি ছিল। কারসন যেমন বলেছিলেন, তেমনই আমি ম্যালোক () ব্যবহার করে এটি স্তূপে বরাদ্দ করে ঠিক করেছি এটি এখন আরও বেশি অর্থবোধ করে।
মাইকেল 11

উত্তর:


78

কারণ তুমি বলেছ

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

পরিবর্তে

struct arg_struct *args = arguments;


4
@ সিগজুইস, এটি আমার পক্ষে কাজ করে না। আমি সংকলন ত্রুটি দেখতে পাচ্ছি: 'শূন্য *' থেকে 'আরগ_স্ট্রিক্ট *' এ অবৈধ রূপান্তর।
নেশতা


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);

বিনামূল্যে আরগস ভুলবেন না! ;)


1

মুদ্রণ_আরগুমেন্টসের আরগগুলি আর্গুমেন্ট, তাই আপনার ব্যবহার করা উচিত:

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 */
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.