微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用pthread的c ++中的生产者-消费者问题

如何解决使用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 举报,一经查实,本站将立刻删除。