Я пытаюсь смоделировать модель производителя-потребителя о многопоточности.
Мы предполагаем, что нужно соблюдать три правила:
- Производитель не может добавить продукт в корзину, когда В ведре полно продуктов.
- Потребитель не может получить продукт из ведра, когда ведро пусто.
- Производство и потребление не могут осуществляться одновременно. Другими словами, эти два действия являются асинхронными.
Теперь, что у меня есть:
- a
int
переменная для хранения количества продуктов в корзине - a
const int
переменная для емкости сегмента, которая в моем коде оценивается как 5. - a
int
переменная для мьютекса, начальное значение 1 - a
vector<HANDLE>
переменная для приостановленного дескриптора, и будет функция планирования этих приостановленных потоков.
Результат: иногда он работает нормально, но иногда становится тупиком. Код и результаты следующие:
код:
#include <iostream>
#include <Windows.h>
#include <vector>
using namespace std;
// the count of product, the initial value is 0
int product_count = 0;
const int product_capacity = 5;
int mutex = 1;
vector<HANDLE> suspendedHandleVector;
HANDLE GetCurrentRealHandle() {
HANDLE realHandle = 0;
return OpenThread(THREAD_ALL_ACCESS, TRUE, GetCurrentThreadId());
}
void ThreadScheduling() {
if (suspendedHandleVector.size() > 0) {
HANDLE handle = suspendedHandleVector[0];
suspendedHandleVector.erase(suspendedHandleVector.begin());
ResumeThread(handle);
}
}
void P() {
--mutex;
if (mutex < 0) {
auto handle = GetCurrentRealHandle();
suspendedHandleVector.push_back(handle);
SuspendThread(handle);
}
}
void V() {
++mutex;
if (mutex >= 0) {
ThreadScheduling();
}
}
DWORD WINAPI ProducerThread(LPVOID param) {
while (true) {
P();
if (product_count == product_capacity) {
V();
continue;
}
++product_count;
cout << "I'm producer, and there are " << product_count << " products now" << endl;
V();
Sleep(100);
}
return 0;
}
DWORD WINAPI ConsumerThread(LPVOID param) {
while (true) {
P();
if (product_count == 0) {
V();
continue;
}
--product_count;
cout << "I'm consumer, and there are " << product_count << " products rest now" << endl;
V();
Sleep(150);
}
return 0;
}
void main() {
auto producer_handle = CreateThread(nullptr, 0, ProducerThread, nullptr, 0, nullptr);
auto consumer_handle = CreateThread(nullptr, 0, ConsumerThread, nullptr, 0, nullptr);
while (true) {
cout << suspendedHandleVector.size() << endl; // This is for debugging
Sleep(100);
}
}
результат, когда он работает, как ожидалось:
0
I'm producer, and there are 1 products now
I'm consumer, and there are 0 products rest now
0
I'm producer, and there are 1 products now
I'm consumer, and there are 0 products rest now
0
I'm producer, and there are 1 products now
0
I'm consumer, and there are 0 products rest now
I'm producer, and there are 1 products now
0
I'm producer, and there are 2 products now
I'm consumer, and there are 1 products rest now
И это ожидаемая бесконечность l oop. Количество продуктов будет равно 4 и 5, потому что я заставляю производителя спать немного больше времени, чем потребителя.
Но вот неожиданный результат:
I'm producer, and there are 5 products now
I'm consumer, and there are 4 products rest now
0
I'm consumer, and there are 4 products rest now
I'm producer, and there are 5 products now
0
0
I'm consumer, and there are 4 products rest now
I'm producer, and there are 5 products now
0
2
2
2
2
2
2
Как мы видим, размер подвешенного вектора резьбы достиг 2 из 0, что не равно 1.
Это просто совпадение, когда два потока были разбужены в то же самое время, когда были конфликтом?
Я считаю, что что-то не так с моим кодом, который нуждается в вашей помощи.
Я также получил проблема во время тестирования: как получить поток и сохранить его в векторе.
Я не уверен, что для этого нужно использовать OpenThread
. Мой курс попросил меня использовать системный вызов, поэтому я не включил thread
headfile.
Спасибо за вашу помощь!