مساعدة مع مفهوم الترابط الشروط الأساسية / سباق

StackOverflow https://stackoverflow.com/questions/416273

  •  03-07-2019
  •  | 
  •  

سؤال

وأنا أتعلم عن المواضيع POSIX الآن، ولكن أعتقد أن هذا هو مجرد سؤال عام على خاصية تعدد، لذلك آمل أن أي شخص يمكن أن تساعدني. لدي هذا المثال من الكتاب الذي أنا أعمل على الذي يدل على حالة سباق:

void *thread_main(void *thread_number) {
    printf("In thread number %d.\n", *(int *)thread_number);
}

void main() {
    int i = 0;
    pthread_t thread;

    for( i = 0; i < 10; i++ ) {
        printf("Creating thread %d.\n");
        pthread_create(&thread, 0, thread_main, &i);
        printf("Created thread %d.\n");
    }
}

وهناك عدد قليل من الأشياء أنا لا أفهم حول هذا الموضوع. أولا، "في عدد موضوع 5." يحصل طبع عدة مرات على الرغم من أنه ليس من المفترض أن يكون في موضوع رقم 5. في الكتاب، يبين المثال موضوع 8 الحصول على طبع عدة مرات. أنا أيضا لا أفهم الجزء الذي يقول *(int *)thread_number. حاولت تغيير هذا لمجرد thread_number، ولكن هذا فقط أعطاني أرقام غريبة مرارا وتكرارا.

والكتاب لا تفسر حقا هذا. يمكن لأي شخص أن تعطيني تفسيرا واضحا ما الذي يحدث هنا؟ أنا لا أفهم لماذا لا يطبع شيئا مثل:

> Creating thread 1.
> In thread number 1.
> Created thread 1.
> Creating thread 2.
> In thread number 2.
> Created thread 2.

وأنا أعلم أن لأنها متعددة مؤشرات الترابط و"في موضوع العدد العاشر". وجزء يأتي في أوقات مختلفة، ولكن في الحقيقة أنا لا أحصل على ماذا لم يكن هناك بالضبط 10 "في عدد موضوع س" مع سطر واحد لكل موضوع أنا خلقت!

~ دس

هل كانت مفيدة؟

المحلول

وأولا إيقاف * (كثافة العمليات *) thread_number هو مؤشر الاشياء - عندما كان لديك فقط thread_number على "أرقام غريبة" كانت عناوين مؤشر إلى 'ط' من <م> الوظيفة الرئيسية (وإلا أنا 'م مخطئا، وكان ينبغي أن يكون كل نفس العدد لتشغيل واحد من برنامج (لذلك كل من المواضيع 10 كان ينبغي أن يكون هو نفسه "في عدد الموضوع [عدد]")).

وتحتاج إلى فهم أن هذه كانت مؤشرات لتكرار 5 إلى معنى - كان كل موضوع يعمل مع نفسه الكامنة أنا من <م> الرئيسية وظيفة - لم يتم نسخها لكل موضوع جديد ، وذلك عندما كان يتم زيادة ط في الرئيسية وظيفة، التي انعكست على thread_number في thread_main وظيفة.

والجزء الاخير من هذا اللغز هو أن الوقت الإعداد لكل موضوع جديد ثم سياق التحول (تغيير الذي موضوع يشغل في الواقع) ليس فوريا، وذلك في قضيتك لحلقة تدير 5 مرات قبل أن المواضيع التي تم إنشاؤها حديثا يتم تشغيل في الواقع (وفي حالة الكتاب، تشغيل للحلقة 8 مرات قبل تبديل السياق)، ثم كل من المواضيع ينظر إلى نفس القيمة ط الأساسية التي هي الآن 5.

نصائح أخرى

ومن الممكن أن للحلقة يمكن تكرار 10 مرة قبل أي من المواضيع 10 التي تم إنشاؤها لديهم فرصة لتشغيل. في هذه الحالة، فإن قيمة *thread_number يكون 10 لكل موضوع (لأنه مؤشر إلى موقع ذاكرة واحدة ذات قيمة واحدة).

إذا كنت لا تمرير مؤشر إلى i إلى pthread_create، ثم قيمة int يختتم يعالجون كعنوان، وذلك عند dereference في thread_main، كنت الوصول إلى بعض مواقع الذاكرة التعسفي، ومحتويات التي ربما غير معروف. كنت محظوظا أن كنت لا segfaulting في هذه الحالة.

إذا كنت تريد أن ترى القيمة الصحيحة ل*thread_number في كل موضوع، هل تريد malloc على int جديدة قبل استدعاء pthread_create وتعيين القيمة الحالية i، كما يلي:

for( i = 0; i < 10; i++ ) {
    int *thread_count = malloc(sizeof(int));
    *thread_count = i;
    printf("Creating thread %d.\n", i);
    pthread_create(&thread, 0, thread_main, thread_count);
    printf("Created thread %d.\n", i);
}

وبطبيعة الحال، ثم كنت بحاجة إلى free الذاكرة عندما تم الخيط معها، كما يلي:

void *thread_main(void *thread_number) {
    printf("In thread number %d.\n", *(int *)thread_number);
    free(thread_numbr);
}

أولا، حالة تعارض أمر سيئ. هذا البرنامج يجب أن <م> لا العمل كما هو متوقع. حالة تعارض يعني أن البرنامج يهدف إلى كسر.

في هذه الحالة يبدو كل المواضيع الخاصة بك هي <م> مشاركة وi متغير. كنت تمريرها ما يشير إلى ذلك، متغير واحد مشترك، وهو أنهم يحاولون تقديم تقرير كلما يحدث للحصول على المقرر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top