سؤال

أحاول حل مشكلة منتج/مستهلك متعدد في لغة C، لكنها لا تعمل كما هو متوقع.فيما يلي بعض التعليمات البرمجية الزائفة لتمثيل التنفيذ الخاص بي.

Thread thread1;
Thread thread2;
Thread thread3;

Data data1;
Mutex data1_mutex;
Semaphore data1_empty;
Semaphore data1_fill;

Data data2;
Mutex data2_mutex;
Semaphore data2_empty;
Semaphore data2_fill;

thread1()
{
   // creates data and places it into data1.

   wait(data1_empty);
   lock(data1_mutex);

   // critical section

   unlock(data1_mutex);
   post(data1_fill);
}

thread2()
{
   // Removes data from data1, processes it, and places it into data2.

   // data1
   wait(data1_fill);
   lock(data1_mutex);

   // data2
   wait(data2_empty);
   lock(data2_mutex);

   // critical section

   // data2
   unlock(data2_mutex);
   post(data2_fill);

   // data1
   unlock(data1_mutex);
   post(data1_empty);
}

thread3()
{
   // Removes data from data2, prints its results, and removes it.

   wait(data2_fill);
   lock(data2_mutex);

   // critical section

   unlock(data2_mutex);
   post(data2_empty);
}

ومع ذلك، مع هذا الحل، سوف تمتلئ البيانات 1، ولكن سيتم قفل مؤشر الترابط 2 ولن يعمل أبدًا.هل هناك خطأ ما في تنفيذي؟

تحرير رقم 1

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

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

المحلول

تأكد من قمت بنشر data1_empty وdata2_empty في البداية.

نصائح أخرى

إذا كنت تستخدم نوعا من الاصطفاف نوع لData، يجب أن تكون قادرة على إزالة الإشارات "فارغة" تماما، إلا إذا كنت تحاول فرض شرط أن كل عمق طابور Data بدقة 0 أو 1. إذا كنت تستخدم متغير محلي في thread2، يمكنك تقليل حجم مقطع حرج.

والتعليمة البرمجية ثم يصبح شيئا من هذا القبيل:

thread1() {
    //Wait for data to put in the queue (i.e. a blocking socket read)
    lock(data1_mutex);
    data1.push(someData);
    unlock(data1_mutex);
    post(data1_fill);
}

thread2() {
    DataType dataElement;
    wait(data1_fill);
    lock(data1_mutex);
    dataElement = data1.pop();
    unlock(data1_mutex);

    lock(data2_mutex);
    data2.push(dataElement);
    unlock(data2_mutex);
    post(data2_fill);
}

thread3() {
    DataType dataElement;
    wait(data2_fill);
    lock(data2_mutex);
    dataElement = data2.pop();
    unlock(data2_mutex);
    //do something with dataElement here
}

ما قاله wrang-wrang، وحاول عدم الضغط على قفل data_1 أثناء انتظار data_2_empty.يمكنك تحقيق ذلك عن طريق الاحتفاظ بمخزن مؤقت بديل لـ data_1 وdata_2 الذي يمكنك تبديله.يقوم Thread_2 بتبديل data_1 أثناء معالجته إلى data_2، ويقوم Thread_3 بتبديل data_2 أثناء معالجته.سيسمح الكود الزائف الحالي الخاص بك بتشغيل الخيط 1 والخيط 3 بشكل متزامن، لكنه لن يسمح بتنفيذ الخيط 2 في نفس الوقت مثل أي من الخيطين الآخرين.

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