如何解决使用pthread的c ++中的生产者-消费者问题
我目前正在学习多线程和信号量,并已被分配为仅使用pthread重现问题。我找到了一个使用std :: thread的解决方案,并且一直在努力将其转换为pthreads,但是pthread_create方法存在问题。
我不确定如何转述
pthread_create(&threads[i],NULL,&Producer::run,&p);
转换为与pthreads兼容的东西。
这是我的完整代码供参考
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <deque>
#include <condition_variable>
#include <semaphore.h>
#include <queue>
#ifdef _WIN32
#include <windows.h>
void sleeps(unsigned milliseconds)
{
Sleep(milliseconds);
}
#else
#include <unistd.h>
void sleeps(unsigned milliseconds) {
usleep(milliseconds * 1000); // takes microseconds
}
#endif
class Widget {
public:
int data;
void setData(int data) {
this->data = data;
}
};
class Buffer
{
public:
void add(Widget widget) {
while (true) {
pthread_mutex_lock(&lock);
sharedBuffer.push_back(widget);
pthread_mutex_unlock(&lock);
return;
}
}
Widget remove() {
while(true) {
pthread_mutex_lock(&lock);
Widget backElem = sharedBuffer.back();
sharedBuffer.pop_back();
pthread_mutex_unlock(&lock);
return backElem;
}
}
Buffer() {}
private:
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
std::deque<Widget> sharedBuffer;
};
class Producer{
Buffer& sharedBuffer;
pthread_mutex_t coutMut;
public:
Producer(Buffer& buffer)
: sharedBuffer(buffer),coutMut(PTHREAD_MUTEX_INITIALIZER)
{}
void run() {
while(true) {
Widget widget;
widget.setData(rand() % 10);
sharedBuffer.add(widget);
pthread_mutex_lock(&coutMut);
std::cout << "Added: " << widget.data << "\n";
sleeps(50);
pthread_mutex_unlock(&coutMut);
}
}
};
class Consumer
{
Buffer& sharedBuffer;
pthread_mutex_t coutMut;
public:
Consumer(Buffer& buffer)
: sharedBuffer(buffer),coutMut(PTHREAD_MUTEX_INITIALIZER)
{}
void run() {
while(true) {
Widget widget;
widget = sharedBuffer.remove();
pthread_mutex_lock(&coutMut);
std::cout << "Removed: " << widget.data << "\n";
sleeps(50);
pthread_mutex_unlock(&coutMut);
}
}
};
int main(int argc,char *argv[]) {
typedef std::string string_std;
const int producerT = std::stoi(argv[1]);
const int consumerT = std::stoi(argv[2]);
int threadSize = producerT + consumerT;
pthread_t threads[threadSize];
void *status;
Buffer b1;
Producer p(b1);
Consumer c(b1);
for (int i = 0; i < producerT; i++) {
pthread_create(&threads[i],&p);
}
for (int i = producerT; i < threadSize; i++) {
pthread_create(&threads[i],&Consumer::run,&c);
}
sleeps(5000);
for (int i = 0; i < threadSize; i++) {
pthread_join(threads[i],&status);
}
exit(0);
}
解决方法
您可能正在寻找这样的东西:
class Producer {
static void static_run(void* pThis) {
static_cast<Producer*>(pThis)->run();
}
void run() {
// Real work done here.
}
};
// At call site
Producer p;
pthread_create(&threads[i],NULL,Producer::static_run,&p);
关键是pthread_create
需要C样式的函数-独立的非成员函数或静态成员函数。因此,您需要一个满足要求的适配器(有时称为“蹦床”),然后转过身来调用成员函数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。