سؤال

بالنظر إلى الكود التالي ، هل يمكنك معرفة ما الذي تسبب في "إدخال 7 أحرف" ظهر 3 مرات خاصة آخر مرة؟

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
void *thread_function(void *arg);
sem_t bin_sem;
#define WORK_SIZE 1024
char work_area[WORK_SIZE];
int main(){
    int res;
    pthread_t a_thread;
    void *thread_result;
    res = sem_init(&bin_sem,0,0);
    if (res!=0){
        perror("Semaphore initialization failed");
        exit(EXIT_FAILURE);
    }
    res = pthread_create(&a_thread,NULL,thread_function,NULL);
    if (res!=0){
        perror("Thread creation failed");
        exit(EXIT_FAILURE);
    }
    printf("Input some text. Enter ‘end’ to finish");
    while (strncmp("end",work_area,3)!=0){
        if(strncmp(work_area,"FAST",4)==0){
            sem_post(&bin_sem);
            strcpy(work_area,"Wheeee...");
        }else{
            fgets(work_area,WORK_SIZE,stdin);
        }
        sem_post(&bin_sem);
    }
    printf("\nWaiting for thread to finish\n");
    res = pthread_join(a_thread,&thread_result);
    if(res!=0){
        perror("Thread join failed!");
        exit(EXIT_FAILURE);
    }
    printf("Thread joined\n");
    sem_destroy(&bin_sem);
    exit(EXIT_SUCCESS);
}
void *thread_function(void* arg){
    sem_wait(&bin_sem);
    while(strncmp("end",work_area,3)!=0){
        printf("You input %d characters\n",strlen(work_area-1));
        sem_wait(&bin_sem);
    }
    pthread_exit(NULL);
}

اختبار الإدخال/الإخراج:

$ cc -D_REENTRANT thread3a.c -o thread3a -lpthread
$ ./thread3a
Input some text. Enter ‘end’ to finish
Excession
You input 9 characters
FAST
You input 7 characters
You input 7 characters
You input 7 characters
end
Waiting for thread to finish...
Thread joined
هل كانت مفيدة؟

المحلول

بعد كتابة "سريع":

  • sem_post (الذي في نهاية الحلقة) --> bin-sem = 1
  • اختبار ما إذا كانت منطقة العمل == النهاية (خطأ)
  • اختبار ما إذا كانت منطقة العمل == سريعة (صحيح)
  • sem_post --> bin-sem = 2
  • منطقة العمل = ياي...
  • sem_post (الذي في نهاية الحلقة) --> bin-sem = 3
  • اختبار ما إذا كانت منطقة العمل == النهاية (خطأ)
  • اختبار ما إذا كانت منطقة العمل = سريعة (خطأ)
  • في انتظار المدخلات

أعتقد أن الخيط الرئيسي له الأولوية حتى يتم حظره عندما يستدعي fgets(..stdin..)، ثم يمكن لوظيفة الخيط تشغيل واستهلاك رمز الإشارة.

هنا أثر لما يحدث.

> Input some text.
  Main thread :
    work_area = ?;
    bin_sem = 0;

  thread function :
    wait on semaphore;

< Excession
  Main thread :
    work_area = Excession;
    bin_sem = 1;

  thread function :
    work_area == Excession; (!= end)
> You input 9 characters; (1)
    bin_sem = 0;
    wait on semaphore;

  Main thread :
    work_area == Excession; (!= end)
    work_area == Excession; (!= FAST)
< FAST
    bin_sem = 1;
    work_area == FAST; (!= end)
    work_area == FAST;
    bin_sem = 2;
    work_area == Wheeee...;
    bin_sem = 3;
    wait on stdin;

  thread function :
    work_area == Wheeee...; (!= end)
> You input 7 characters; (Why seven?)
    bin_sem = 3-1 = 2;
> You input 7 characters; (Why seven?)
    bin_sem = 2-1 = 1;
> You input 7 characters; (Why seven?)
    bin_sem = 1-1 = 0;
    wait on semaphore;

نصائح أخرى

وهذا الخط هو الخطأ في وظيفة موضوع.

printf("You input %d characters\n",strlen(work_area-1));

ويجب أن strlen(work_area)، وليس strlen(work_area-1).

لا يظهر الإخراج ليكون من الإصدار المدرجة من قانون:

وprintf ( "إدخال بعض النص")؛

لا يمكن ان تنتج:

وإدخال بعض النص. أدخل 'نهاية' لإنهاء

وكما كنت قد الانقسام أكثر أو أقل لك السيطرة حلقة بطريقة متقطعة بين اثنين من المواضيع، ومن ثم تربطهم مع متغير عمومي. انها نوع من "غوتو" البناء النوع الذي يسأل فقط عن المتاعب ...

وبول.

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