مسئله خواننده-نویسنده
اولین مسئله خواننده و نویسنده‌ها

فرض کنید که ما یک ناحیه مشترک حافظه (ناحیه بحرانی) با محدودیت‌های اساسی ذکر شده در بالا داریم. این امکان وجود دارد تا داده مشترک را در پشت یک انحصار متقابل، mutex، حفاظت کنیم. در این حالت دو ریسه به‌طور همزمان نمی‌توانند به داده دسترسی پیدا کنند. با این حال، این راه حل بهترین راه حل نیست؛ زیرا این امکان وجود دارد که یک خواننده مثلاً با نام R1 قفل را داشته باشد و سپس خوانندهٔ دیگری مثلاً با نام R2 درخواست دسترسی کند. منطقی نیست که R2 منتظر بماند تا R1 کارش تمام شود و سپس عملیات خواندن را شروع کند، در عوض، R2 باید این اجازه را داشته باشد که همزمان با R1 منبع را بخواند؛ زیرا عملیات خواندن موجب تغییر داده نمی‌شود؛ بنابراین خواندن‌های همزمان بی خطر هستند. این شرایط انگیزه‌ای برای حل اولین مشکل خواننده ها- نویسنده‌ها هست که در آن محدودیت‌هایی اضافه می‌شود که اگر منبع مشترک در حال حاضر برای خواندن باز باشد، هیچ خواننده ای نباید منتظر بماند. به این راه حل، اولویت خواننده‌ها می‌گویند و کد آن در زیر نشان داده شده‌است:
semaphore resource=1;
semaphore rmutex=1;
readcount=0;
 resource.P() is equivalent to wait(resource)
 resource.V() is equivalent to signal(resource)
 rmutex.P() is equivalent to wait(rmutex)
 rmutex.V() is equivalent to signal(rmutex)
*/

writer() {
 resource.P();          //Lock the shared file for a writer

 <CRITICAL Section>
 // Writing is done

 <EXIT Section>
 resource.V();          //Release the shared file for use by other readers. Writers are allowed if there are no readers requesting it.
}

reader() {
 rmutex.P();           //Ensure that no other reader can execute the <Entry> section while you are in it
 <CRITICAL Section>
 readcount++;          //Indicate that you are a reader trying to enter the Critical Section
 if (readcount == 1)   //Checks if you are the first reader trying to enter CS
 resource.P();     //If you are the first reader, lock the resource from writers. Resource stays reserved for subsequent readers
 <EXIT CRITICAL Section>
 rmutex.V();           //Release

 // Do the Reading

 rmutex.P();           //Ensure that no other reader can execute the <Exit> section while you are in it
 <CRITICAL Section>
 readcount--;          //Indicate that you are no longer needing the shared resource. One fewer reader
 if (readcount == 0)   //Checks if you are the last (only) reader who is reading the shared file
 resource.V();     //If you are last reader, then you can unlock the resource. This makes it available to writers.
 <EXIT CRITICAL Section>
 rmutex.V();           //Release
}
در این راه حل برای مسئله خواننده ها/ نویسنده‌ها، اولین خواننده باید منبع (فایل مشترک) را قفل کند، البته اگر منبعی وجود داشته باشد. زمانی که فایل در برابر نویسنده‌ها قفل شد، خواننده‌های بسیار دیگری، بدون اینکه مجبور باشند قفل آن را مجدداً باز کنند، می‌توانند از آن استفاده کنند.
قبل از ورود به ناحیه بحرانی، هر خوانندهٔ جدید باید از منطقه ورود عبور کند. با این حال، ممکن است در یک لحظه فقط یک خواننده در منطقه ورود وجود داشته باشد. این کار برای این انجام می‌شود تا شرایط رقابتی بین خواننده‌ها به وجود نیاید (در این بستر، شرایط رقابتی شرایطی است که در آن دو یا بیش از دو ریسه به‌طور همزمان از خواب بیدار می‌شوند و تلاش می‌کنند تا وارد بخش بحرانی شوند؛ بدون محدودیت‌های بیشتر، این رفتار نامعین است؛ یعنی دو خواننده به صورت همزمان readcount را افزایش می‌دهند و هر دو سعی می‌کنند تا منبع را قفل کنند. این کار موجب می‌شود تا یک خواننده مسدود شود). برای عملی کردن این روش هر خواننده که وارد بخش ورود می‌شود، بخش ورود را برای خودش قفل می‌کند تا زمانی که کارش تمام شود. در طی این زمان، خوانندهٔ مذکور منبع را قفل نمی‌کند، و فقط منطقه ورود را قفل می‌کند تا هیچ خواننده دیگری در حالی که او در داخل آن قرار دارد، نتواند وارد این بخش شود. زمانی که خوانندهٔ مذکور اجرای منطقهٔ شروع را به پایان رساند، با سیگنال دهی به mutex قفل آن را باز می‌کند. سیگنال دهی از طریق ()mutex.V در کد بالا انجام می‌شود. برای بخش خروج نیز وضعیت همین است. در یک لحظه بیش از یک خواننده نمی‌تواند در بخش خروج قرار بگیرد، بنابراین هر خواننده ای قبل از استفاده از بخش خروج باید بخش خروج را در اختیار بگیرد و قفل کند.
زمانی که اولین خواننده در بخش ورود هست، منبع را قفل خواهد کرد. با این کار، هیچ نویسنده‌ای اجازهٔ دسترسی به آن را نخواهد داشت. خواننده‌های بعدی فقط می‌توانند از منبع قفل شده (در برابر نویسنده‌ها) استفاده کنند. خواننده ای که آخر از همه تمام می‌کند (توسط متغیر readcount نشان داده می‌شود) باید قفل منبع را باز کند تا منبع در اختیار نویسندگان قرار بگیرد.
در این روش هر نویسنده‌ای باید به‌طور جداگانه مالکیت منبع را در اختیار بگیرد. این بدان معنا است که تعداد زیادی از خواننده‌های متوالی، بعداً می‌توانند دسترسی تمام نویسنده‌های بالقوه را به منبع قفل کنند و آنها را با قحطی منبع مواجه سازند. علت این پدیده این است که بعد از اینکه اولین خواننده منبع را قفل کرد، هیچ نویسنده ای نمی‌تواند آن را قفل کند، تا زمانی که آزاد شود و فقط توسط آخرین خواننده آزاد خواهد شد. از این رو این راه حل منصفانه نیست.