Producer-Consumer Problem in c++ using pthread - c++

I am currently learning multithreading and semaphores and have been assigned to recreate the problem using only pthread. I found a solution that uses std::thread and have been working to convert it to pthreads, but I am having problems with the pthread_create method.
I am not sure specifically how to turn this statement
pthread_create(&threads[i], NULL, &Producer::run, &p);
into something that works with pthreads.
Here is my whole code for reference
#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], NULL, &Producer::run, &p);
}
for (int i = producerT; i < threadSize; i++) {
pthread_create(&threads[i], NULL, &Consumer::run, &c);
}
sleeps(5000);
for (int i = 0; i < threadSize; i++) {
pthread_join(threads[i], &status);
}
exit(0);
}

You are probably looking for something like this:
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);
The point is that pthread_create wants a C-style function - either a standalone non-member function, or a static member function. So you need an adapter (sometimes referred to as a "trampoline") that satisfies the requirements, and then turns around and calls the member function.

Related

How to pass or share mutex in class member in c++

I want to develop a logger class. So I decided put all related code to the read operation in the
dataLogger class.
In the dataLogger with a thread, I want to able write data in a buffer, which named “queue_”. In main class that contains an object of dataLogger, I want to able read from the “queue_” with another thread. Therefore, I use shared_pointer to access the buffer.
Is it possible to use one mutex to manage read and write operation?
Actually, I want to pass the mutex witch created in main class to the dataLogger class.
I used QtGuiApplication to illustrate my problem.
In main.cpp
#include "QtGuiApplication8.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtGuiApplication8 w;
w.show();
return a.exec();
}
In QtGuiApplication8.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtGuiApplication8.h"
#include <thread>
#include <mutex>
#include <vector>
#include "dataLogger.h"
using namespace std;
class QtGuiApplication8 : public QMainWindow
{
Q_OBJECT
public:
QtGuiApplication8(QWidget *parent = Q_NULLPTR);
private:
Ui::QtGuiApplication8Class ui;
std::thread thread_;
bool thread_flag = false;
void thread_fn();
std::mutex mutex_;
shared_ptr < vector<std::shared_ptr<vector<uint8_t>>>> queue_;
dataLogger dataLogger_;
};
In QtGuiApplication8.cpp
#include "QtGuiApplication8.h"
QtGuiApplication8::QtGuiApplication8(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
queue_ = make_shared< vector<std::shared_ptr<vector<uint8_t>>>>();
dataLogger_.setQueue(queue_);
// setMutex(mutex_); //I want same thing like this line !
dataLogger_.run();
thread_flag = true;
thread_ = std::thread(&QtGuiApplication8::thread_fn, this);
}
void QtGuiApplication8::thread_fn()
{
while (thread_flag)
{
while (queue_->size() != 0)
{
{
std::lock_guard<std::mutex> f(mutex_);
// auto scan_raw = queue_->back(); // at this line I want to read queue_
}
}
Sleep(20);
}
}
dataLogger.h
#pragma once
#include <thread>
#include <mutex>
#include <vector>
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
using namespace std;
class dataLogger
{
public:
void setQueue(shared_ptr<vector<shared_ptr<vector<uint8_t>>>> q) { queue_ = q; };
//void setMutex(mutex* m) { mutex_ = *m; }; //I want same thing like this line !
void run();
void stop();
private:
std::thread thread_;
bool thread_flag = false;
void thread_fn();
std::mutex mutex_;
shared_ptr<vector<std::shared_ptr<vector<uint8_t>>>> queue_;
};
dataLogger.cpp
#include "dataLogger.h"
void dataLogger::run()
{
thread_flag = true;
thread_ = std::thread(&dataLogger::thread_fn, this);
}
void dataLogger::stop()
{
thread_flag = false;
if (thread_.joinable())
thread_.join();
}
void dataLogger::thread_fn()
{
std::shared_ptr<vector<uint8_t>> rawData_;
rawData_ = std::make_shared<vector<uint8_t>>(10);
vector<uint8_t> sasaa;
while (thread_flag)
{
{
std::lock_guard<std::mutex> f(mutex_);
for (size_t i = 0; i < 10; i++)
rawData_->at(i) = i; // simulation data source
queue_->push_back(rawData_);
}
rawData_ = std::make_shared<vector<uint8_t>>(10);
Sleep(20);
}
}

Multiple thread pause/resume

Main thread uses group of threads to search. First solution (test1) is often creating , waiting - join() and destroying threads. This works but has overhead. I try using mutex and condition_variable, but this not works,. especially for number searching threads>1.
My code:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
using namespace std;
const int NThr = 2;
struct InterchangeData {
bool endflag=false;
mutex chg_mutex;
condition_variable condition;
};
InterchangeData data;
bool execute1(InterchangeData* xchgData) {
for (int i=0; i<10; i++) {
if (xchgData->endflag) return false;
this_thread::sleep_for(chrono::milliseconds(rand()%10 +1 ));
if (rand()%100 == 50) {
lock_guard<mutex> lock(xchgData->chg_mutex);
if (!xchgData->endflag) {
printf("found!");
xchgData->endflag = true;
return true;
}
}
}
return false;
}
bool execute2(InterchangeData* xchgData) {
while (true) {
{
unique_lock<mutex> lock(xchgData->chg_mutex);
xchgData->condition.wait(lock);
}
int ret=2;
if (xchgData->endflag) ret=0;
if (execute1(xchgData)) ret=1;
{
unique_lock<mutex> lock(xchgData->chg_mutex);
xchgData->condition.notify_one();
this_thread::sleep_for(chrono::milliseconds(1));
if (ret==0) return false;
else if (ret==1) return true;
}
}
}
vector<thread*> threads;
typedef bool (*functype)(InterchangeData*);
void start(functype execute) {
for (int i=0; i<NThr; i++) {
auto t = new thread(execute, &data);
threads.push_back(t);
}
}
void stop() {
for (auto t : threads) {
t->join();
delete t;
}
threads.clear();
}
void test1() {
for (int i=0; i<10; i++) {
start(&execute1);
stop();
}
}
void test2() {
start(&execute2);
this_thread::sleep_for(chrono::milliseconds(100));
for (int i=0; i<10; i++) {
{
unique_lock<mutex> lock(data.chg_mutex);
data.condition.notify_one();
this_thread::sleep_for(chrono::milliseconds(1));
}
{
unique_lock<mutex> lock(data.chg_mutex);
data.condition.wait(lock);
}
}
{
unique_lock<mutex> lock(data.chg_mutex);
data.condition.notify_one();
this_thread::sleep_for(chrono::milliseconds(1));
}
stop();
}
int main() {
test2();
return 0;
}
Problem: is possible fast pausing/resuming execute function and main thread using condition_variable,unique_lock and wait/notify_one ?

How to prevent the usage of the same object on compile time?

I have wrote the small timer using pthreads. The code is rather simple
#include <cassert>
#include <ctime>
#include <iostream>
#include <limits>
#include <pthread.h>
#include <stdio.h>
#include <string>
class timer
{
public:
timer(const std::clock_t sec): m_sec(sec) {}
void set_time(const std::clock_t sec)
{
m_sec = sec;
}
void start()
{
_start_time = std::clock();
}
void restart()
{
_start_time = std::clock();
}
bool tick()
{
for(double elpsd = elapsed(); elpsd <= m_sec; elpsd = elapsed())
{
if(elpsd <= m_sec) {}
}
return true;
}
double elapsed() const
{
return double(std::clock() - _start_time) / CLOCKS_PER_SEC;
}
double elapsed_max() const
{
return (double((std::numeric_limits<std::clock_t>::max)()) - double(_start_time)) / double(CLOCKS_PER_SEC);
}
double elapsed_min() const
{
return double(1)/double(CLOCKS_PER_SEC);
}
private:
std::clock_t _start_time;
std::clock_t m_sec;
};
class worker
{
public:
void operator ()()
{
start();
}
virtual void start() = 0;
virtual ~worker() = 0;
};
inline worker::~worker()
{
}
class some_worker : public worker
{
std::string msg;
public:
some_worker(std::string p_msg) :
msg(p_msg)
{
}
~some_worker(){}
void start()
{
std::cout << msg << std::endl;
}
};
class timer_handler
{
worker* work;
pthread_t id;
pthread_attr_t attr;
timer* m_timer;
public:
timer_handler(const timer* const tm, const worker* const p_work)
{
assert(p_work != 0);
work = const_cast<worker*>(p_work);
pthread_attr_init(&attr);
assert(tm != 0);
m_timer = const_cast<timer*>(tm);
}
void start()
{
pthread_create(&id, &attr, (void* (*)(void*))&run, this);
}
static void run(timer_handler *working_class)
{
working_class->m_timer->start();
while(1) {
if(working_class->m_timer->tick()) {
working_class->work->operator()();
working_class->m_timer->restart();
}
}
}
int join()
{
return pthread_join(id, NULL);
}
~timer_handler()
{
pthread_attr_destroy(&attr);
delete work;
delete m_timer;
}
};
int main(int argc, char *argv[])
{
some_worker* wrk = new some_worker("Worker no: 1");
some_worker* wrk_2 = new some_worker("Worker no: 2");
timer* tm = new timer(1);
timer_handler* handler = new timer_handler(tm, wrk);
timer_handler* handler_2 = new timer_handler(tm, wrk_2);
handler->start();
handler_2->start();
handler->join();
handler_2->join();
return 0;
}
But the in the main() these two handlers are use the same timer and it can be the cause of problem, because f.e. one thread can call timer->start(), another can call restart() and etc. The question is how to prevent the usage of the same object on compile time instead of using mutex which can be useful only on run-time.

how to show output from api function?

Sorry for basic question. I'm trying to show json in QPlainTextWidget. I have api function which have console output and contains all needed data. Looks like that:
int iperf_run_server(struct iperf_test *test)
{
int result, s, streams_accepted;
fd_set read_set, write_set;
struct iperf_stream *sp;
struct timeval now;
struct timeval* timeout;
......
if (test->json_output)
if (iperf_json_start(test) < 0)
return -1;
if (test->json_output) {
cJSON_AddItemToObject(test->json_start, "version", cJSON_CreateString(version));
cJSON_AddItemToObject(test->json_start, "system_info", cJSON_CreateString(get_system_info()));
} else if (test->verbose) {
iprintf(test, "%s\n", version);
iprintf(test, "%s", "");
fflush(stdout);
printf("%s\n", get_system_info());
}
.....
cleanup_server(test);
if (test->json_output) {
if (iperf_json_finish(test) < 0)
return -1;
}
....
return 0;
}
For now I have first thread with my gui, and second thread, contains class which run this function on a signal. All things works normally, but i'm not fully understand, how I can "stop" iperf_run_server for "reading/buffering" output, without any changes in api.
The simplest thing to do would be to collect each message in a string, and emit a signal from the object running in the second thread. You can connect that signal to a slot in an object in the GUI thread.A zero-timeout timer is invoked each time the event loop is done processing other events - it is a useful mechanism to leverage to run things "continuously".
For example:
#include <QApplication>
#include <QPlainTextEdit>
#include <QThread>
#include <QBasicTimer>
#include <QTextStream>
//! A thread that's always safe to destruct.
class Thread : public QThread {
private:
// This is a final class.
using QThread::run;
public:
Thread(QObject * parent = 0) : QThread(parent) {}
~Thread() {
quit();
wait();
}
};
class IperfTester : public QObject {
Q_OBJECT
struct Test { int n; Test(int n_) : n(n_) {} };
QList<Test> m_tests;
QBasicTimer m_timer;
public:
IperfTester(QObject * parent = 0) : QObject(parent) {
for (int i = 0; i < 50; ++i) m_tests << Test(i+1);
}
//! Run the tests. This function is thread-safe.
Q_SLOT void runTests() {
QMetaObject::invokeMethod(this, "runTestsImpl");
}
Q_SIGNAL void message(const QString &);
private:
Q_INVOKABLE void runTestsImpl() {
m_timer.start(0, this);
}
void timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) return;
if (m_tests.isEmpty()) {
m_timer.stop();
return;
}
runTest(m_tests.first());
m_tests.removeFirst();
}
void runTest(Test & test) {
// do the work
QString msg;
QTextStream s(&msg);
s << "Version:" << "3.11" << "\n";
s << "Number:" << test.n << "\n";
emit message(msg);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPlainTextEdit log;
// This order is important: the thread must be defined after the object
// to be moved into the thread.
IperfTester tester;
Thread thread;
tester.moveToThread(&thread);
thread.start();
log.connect(&tester, SIGNAL(message(QString)), SLOT(appendPlainText(QString)));
log.show();
tester.runTests();
return a.exec();
// Here, the thread is stopped and destructed first, following by a now threadless
// tester. It would be an error if the tester object was destructed while its
// thread existed (even if it was stopped!).
}
#include "main.moc"

pthread input thread and worker thread synchronization

I have two pthreads one of them is reading from cin and putting it in a QUEUE and the other one is a worker thread checking the QUEUE every 2 seconds and printing something if there is something in it.
This is what's in my main:
#include <string>
#include <queue>
#include <iostream>
#include <stdio.h>
#include "Thread.h"
#include "Mutex.h"
using namespace std;
queue<string> lineup;
Mutex lock;
class InputReader:public Thread{
private:
string buffer;
protected:
virtual void run(){
while(true){
cout << "Please Enter some Text:\n" ;
getline(cin,buffer);
lock.lock();
lineup.push(buffer);
lock.unlock();
}
}
public:
InputReader(){}
~InputReader(){}
};
class Request: public Thread{
protected:
virtual void run(){
while(true){
sleep(2);
lock.lock();
if ((int)(lineup.size())>0){
cout << "Sending Request: " << lineup.front() << endl;
lineup.pop();
}
else{
cout << "Nothing to send!" <<endl;
}
lock.unlock();
}
}
public:
Request(){}
~Request(){}
};
int main(){
Request rq;InputReader iread;
iread.start(); rq.start();
iread.join(); rq.join();
return 0;
}
Where Thread.h and Thread.cpp are:
#ifndef __THREAD_H__
#define __THREAD_H__
#include <pthread.h>
class Thread
{
private:
pthread_t thread;
static void * dispatch(void *);
protected:
virtual void run() = 0;
public:
virtual ~Thread();
void start();
void join();
};
#endif
// THREAD.CPP
#include "Thread.h"
Thread::~Thread(){}
void * Thread::dispatch(void * ptr)
{
if (!ptr) return 0;
static_cast<Thread *>(ptr)->run();
pthread_exit(ptr);
return 0;
}
void Thread::start(){
pthread_create(&thread, 0, Thread::dispatch, this);
}
void Thread::join()
{
pthread_join(thread, 0);
}
Mutex.h and Mutex.cpp:
#ifndef __MUTEX_H__
#define __MUTEX_H__
#include <pthread.h>
class Mutex
{
private:
pthread_mutex_t mutex;
public:
Mutex();
~Mutex();
void lock();
void unlock();
bool trylock();
};
#endif
// MUTEX.CPP -----------------------
#include "Mutex.h"
Mutex::Mutex(){
pthread_mutex_init(&mutex, 0);
}
Mutex::~Mutex(){
pthread_mutex_destroy(&mutex);
}
void Mutex::lock(){
pthread_mutex_lock(&mutex);
}
void Mutex::unlock(){
pthread_mutex_unlock(&mutex);
}
bool Mutex::trylock() {
return (pthread_mutex_trylock(&mutex) == 0);
}
The problem is once its in the infinite loop waiting for stdin in the iread thread, the rq thread never starts. In fact, whichever .start() comes first is the one it gets stuck in... any ideas?
Turned out that I needed to run g++ with the -lpthread option. Does anyone know why this isn't on by default?