Я изучаю параллелизм с C ++ 11 в настоящее время. Я написал кусок кода для курсовой работы. Однако код не завершает работу.
Моя среда:
Система: Windows 10
Компилятор: mingw-w64x86_64-8.1.0-posix-seh-rt_v6-rev0
Обновление:
Я думал, что "соединение" может закончить поток. Спасибо тем приятным парням, которые прокомментировали вопрос, я понял, что "присоединиться" не "убьет" ветку. Эта функция возвращает, когда выполнение потока завершено. Кроме того, проблема в моем коде, возможно, связана с тупиком. Я попробовал несколько способов решить эту проблему. Однако это также не работает.
Что я пробовал: добавление
if(ConsumerPtr->isConsumerDead()){
break;
}
в функцию void Producer::prods();
. Это не работаетПозже я редактирую еще немного. Я добавил новую глобальную переменную, чтобы проверить, перестал ли потребитель работать. Кроме того, я добавил еще оператор if для проверки потребителя в районе void Buffer::put();
. После этого я обнаружил, что код редко работает, но в большинстве случаев не работает. Я попытался отредактировать код std::this_thread::sleep_for(std::chrono::milliseconds(60));
времени ожидания после операции однократного использования / производства. Я увеличил 10 мс до 60 мс. Тогда код работает намного лучше. Теперь это редко терпит неудачу.
Я думаю, что код не заканчивается, потому что во время работы тупик. Я нашел причину, которая может привести к взаимоблокировке в Wiki: тупик возникает, когда процесс или поток переходит в состояние ожидания, поскольку запрошенный системный ресурс удерживается другим ожидающим процессом, который, в свою очередь, ожидает другого ресурса, удерживаемого другим ожидающим процессом. Если процесс не может изменить свое состояние на неопределенный срок, поскольку запрашиваемые им ресурсы используются другим ожидающим процессом, то говорят, что система находится в тупике.
Итак, возникает вопрос: действительно ли этотупик? Как избежать тупика? что я должен отредактировать, чтобы улучшить мой код?
Вот новый код:
#include <iostream>
#include <thread>
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
using namespace std;
std::mutex mu; //mutex
//std::unique_lock<mutex> locker(mu); //unique_lock
std::condition_variable cond;
std::mutex m_mutex;
int consumerRunTurns = 0;
class Buffer {
public:
Buffer():count(0) {}
void put();
int get();
bool isBufferEmpty();
bool isBufferFull();
private:
int count;
}; //end class Buffer
//Thread Class and Functions inside:
class Consumer{
public:
Consumer(Buffer* cbptr);
void cons();
bool isConsumerDead();
private:
Buffer* BufferPtr;
};
class Producer{
public:
Producer(Buffer* pbptr, Consumer* coptr);
void prods();
private:
Buffer* BufferPtr;
Consumer* ConsumerPtr;
};
int main(){
Buffer* tc = new Buffer();
Consumer* cdtc = new Consumer(tc);
Producer* pdtc = new Producer(tc,cdtc);
std::thread t[5]; //declare an array of thread objects
int i = 0;
for(; i<3; ++i){
t[i]=std::thread(&Producer::prods,std::ref(pdtc));
}
for(; i<5; ++i){
t[i]=std::thread(&Consumer::cons,std::ref(cdtc));
}
cout << "Debug1" << endl;
cout << "Debug1" << endl;
cout << "Debug1" << endl;
for(i = 0; i<5; ++i){
t[i].join();
cout << "now i is :" << i << endl;
}
cout << "All threads terminated" << endl;
return 0;
}
void Buffer::put(){
std::unique_lock<mutex> locker(mu); //unique_lock
if(consumerRunTurns>=200){
cond.notify_one();
return;
}
while(isBufferFull()==1){
if(consumerRunTurns>=200){
cond.notify_one();
break;
}
cond.wait(locker);
}
if(consumerRunTurns>=200){
return;
}
if(isBufferFull()==0)
cond.notify_one();
++count;
std::cout << "producer thread" << this_thread::get_id() << ",count = " << count << endl;
}
int Buffer::get(){
std::unique_lock<mutex> locker(mu); //unique_lock
while(isBufferEmpty()==1){
cond.wait(locker);
}
if(isBufferEmpty()==0)
cond.notify_one();
--count;
std::cout << "consumer thread" << this_thread::get_id() << ",count = " << count << endl;
return count;
}
bool Buffer::isBufferEmpty(){
if(count <=0){
std::cout << "buffer is empty, consumer thread" << this_thread::get_id() << " is about to suspend." << endl;
return 1;
}
else
return 0;
}
bool Buffer::isBufferFull(){
if(count >=10){
std::cout << "buffer is full, producer thread" << this_thread::get_id() << " is about to suspend." << endl;
return 1;
}
else
return 0;
}
Consumer::Consumer(Buffer* cbptr):BufferPtr(cbptr){
}
bool Consumer::isConsumerDead(){
if(consumerRunTurns >= 200){
cout << "consumer Dead" << endl;
cout << "consumer Dead" << endl;
cout << "consumer Dead" << endl;
return 1;
}
else
return 0;
}
void Consumer::cons(){
for(int i = 0; i<100; ++i){
BufferPtr->get();
std::this_thread::sleep_for(std::chrono::milliseconds(60));
}
consumerRunTurns+=100;
}
Producer::Producer(Buffer* pbptr, Consumer* coptr):BufferPtr(pbptr), ConsumerPtr(coptr){}
void Producer::prods(){
for(int i = 0; i<100; ++i){
if(ConsumerPtr->isConsumerDead()){
break;
}
BufferPtr->put();
std::this_thread::sleep_for(std::chrono::milliseconds(60));
}
}
Предыдущий код:
#include <iostream>
#include <thread>
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
using namespace std;
std::mutex mu; //mutex
//std::unique_lock<mutex> locker(mu); //unique_lock
std::condition_variable cond;
std::mutex m_mutex;
class Buffer {
public:
Buffer():count(0) {}
void put();
int get();
bool isBufferEmpty();
bool isBufferFull();
private:
int count;
}; //end class Buffer
//Thread Class and Functions inside:
class Consumer{
public:
Consumer(Buffer* cbptr);
void cons();
bool isConsumerDead();
private:
Buffer* BufferPtr;
int consumerDeadFlag;
};
class Producer{
public:
Producer(Buffer* pbptr, Consumer* coptr);
void prods();
private:
Buffer* BufferPtr;
Consumer* ConsumerPtr;
};
int main(){
Buffer* tc = new Buffer();
Consumer* cdtc = new Consumer(tc);
Producer* pdtc = new Producer(tc,cdtc);
std::thread t[5]; //declare an array of thread objects
int i = 0;
for(; i<3; ++i){
t[i]=std::thread(&Producer::prods,std::ref(pdtc));
}
for(; i<5; ++i){
t[i]=std::thread(&Consumer::cons,std::ref(cdtc));
}
cout << "Debug1" << endl;
cout << "Debug1" << endl;
cout << "Debug1" << endl;
for(i = 0; i<5; ++i){
t[i].join();
cout << "now i is :" << i << endl;
}
cout << "All threads terminated" << endl;
return 0;
}
void Buffer::put(){
std::unique_lock<mutex> locker(mu); //unique_lock
while(isBufferFull()==1){
cond.wait(locker);
}
if(isBufferFull()==0)
cond.notify_one();
++count;
std::cout << "producer thread" << this_thread::get_id() << ",count = " << count << endl;
}
int Buffer::get(){
std::unique_lock<mutex> locker(mu); //unique_lock
while(isBufferEmpty()==1){
cond.wait(locker);
}
if(isBufferEmpty()==0)
cond.notify_one();
--count;
std::cout << "consumer thread" << this_thread::get_id() << ",count = " << count << endl;
return count;
}
bool Buffer::isBufferEmpty(){
if(count <=0){
std::cout << "buffer is empty, consumer thread" << this_thread::get_id() << " is about to suspend." << endl;
return 1;
}
else
return 0;
}
bool Buffer::isBufferFull(){
if(count >=10){
std::cout << "buffer is full, producer thread" << this_thread::get_id() << " is about to suspend." << endl;
return 1;
}
else
return 0;
}
Consumer::Consumer(Buffer* cbptr):BufferPtr(cbptr){
consumerDeadFlag = 0;
}
bool Consumer::isConsumerDead(){
if(consumerDeadFlag > 1){
cout << "consumer Dead" << endl;
cout << "consumer Dead" << endl;
cout << "consumer Dead" << endl;
return 1;
}
else
return 0;
}
void Consumer::cons(){
for(int i = 0; i<100; ++i){
BufferPtr->get();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
++consumerDeadFlag;
}
Producer::Producer(Buffer* pbptr, Consumer* coptr):BufferPtr(pbptr), ConsumerPtr(coptr){}
void Producer::prods(){
for(int i = 0; i<100; ++i){
if(ConsumerPtr->isConsumerDead()){
break;
}
BufferPtr->put();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
Вывод:
producer threadDebug12,count = 1
producer thread4,count = 2
producer thread3,count = 3
Debug1
Debug1
consumer thread5,count = 2
consumer thread6,count = 1
producer thread2,count = 2
consumer thread5,count = 1
producer thread4,count = 2
producer thread3,count = 3
consumer thread6,count = 2
producer thread2,count = 3
producer thread4,count = 4
producer thread3,count = 5
consumer thread5,count = 4
consumer thread6,count = 3
producer thread2,count = 4
producer thread4,count = 5
consumer thread5,count = 4
producer thread3,count = 5
consumer thread6,count = 4
producer thread2,count = 5
consumer thread5,count = 4
producer thread4,count = 5
producer thread3,count = 6
consumer thread6,count = 5
producer thread2,count = 6
producer thread4,count = 7
producer thread3,count = 8
consumer thread5,count = 7
consumer thread6,count = 6
producer thread2,count = 7
consumer thread5,count = 6
producer thread4,count = 7
producer thread3,count = 8
consumer thread6,count = 7
producer thread2,count = 8
consumer thread5,count = 7
producer thread4,count = 8
producer thread3,count = 9
consumer thread6,count = 8
producer thread2,count = 9
producer thread4,count = 10
consumer thread5,count = 9
producer thread3,count = 10
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread3 is about to suspend.
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
buffer is full, producer thread4 is about to suspend.
consumer thread5,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
buffer is full, producer thread2 is about to suspend.
consumer thread6,count = 9
producer thread4,count = 10
buffer is full, producer thread2 is about to suspend.
consumer thread5,count = 9
producer thread2,count = 10
buffer is full, producer thread3 is about to suspend.
consumer thread6,count = 9
producer thread3,count = 10
buffer is full, producer thread4 is about to suspend.
buffer is full, producer thread2 is about to suspend.
и т. Д. (из-за ограничения слов)
consumer Dead
consumer Dead
consumer Dead