linux C++ thread in class - c++

Hi i want to do the class with method which will start in separate thread after creating class. That how i do that:
class Devemu {
int VarInc;
void Increm() {
for(;;) {
if (VarInc > 532) VarInc = 0;
else VarInc++;
}
}
public:
static void* IncWrapper(void* thisPtr) {
((Devemu*) thisPtr)->Increm();
return NULL;
}
Devemu() {
VarInc = 0;
}
int Var() {
return VarInc;
}
};
int main(int argc, char** argv) {
Devemu* em = new Devemu();
pthread_t thread_id;
pthread_create(&thread_id, NULL, &Devemu::IncWrapper, NULL);
for(int i = 0 ;i < 50; i++) {
printf("%d\n", em->Var());
}
return (EXIT_SUCCESS);
}
I unlike that pthread_create in main and IncWrapper method can i change that?

Yes, you can put it in the constructor if you like :
class Devemu {
int VarInc;
pthread_t thread_id;
void Increm() {
for(;;) {
if (VarInc > 532) VarInc = 0;
else VarInc++;
}
}
public:
static void* IncWrapper(void* thisPtr) {
((Devemu*) thisPtr)->Increm();
return NULL;
}
Devemu() {
VarInc = 0;
pthread_create(&thread_id, NULL, &Devemu::IncWrapper, NULL);
}
int Var() {
return VarInc;
}
};

I suppose it's better to put the thread creation in the separate member-function like that:
class Devemu {
...
void run()
{
pthread_create(&thread_id, NULL, &Devemu::IncWrapper, NULL);
}
...
};
Not actually in ctor, because sometimes you (or anyone who uses your code) can forget that thread created in the ctor and start coding like:
Devemu m;
...
Devemu m1;
...
creating unnecessary threads just like instances of the class.

If you want to get working source code you need make next changes:
--- so0.cpp 2019-11-04 11:26:11.101984795 +0000
+++ so1.cpp 2019-11-04 11:26:57.108501816 +0000
## -1,3 +1,7 ##
+#include "stdio.h"
+#include <pthread.h>
+#include <cstdlib>
+
class Devemu {
int VarInc;
## -24,7 +28,7 ##
Devemu* em = new Devemu();
pthread_t thread_id;
-pthread_create(&thread_id, NULL, &Devemu::IncWrapper, NULL);
+pthread_create(&thread_id, NULL, &Devemu::IncWrapper, em);
My variant for resolving your problem is :
#include "stdio.h"
#include <pthread.h>
#include <cstdlib>
#include <unistd.h>
class Devemu {
private:
int VarInc;
pthread_attr_t attr; /* отрибуты потока */
pthread_t thread_id;
void Increm();
public:
static void* IncWrapper (void* thisPtr);
Devemu();
~Devemu();
int Var();
};
void Devemu::Increm() {
while (true) {
if (VarInc > 532) { VarInc = 0; } else { VarInc++; }
}
}
void* Devemu::IncWrapper(void* thisPtr) {
((Devemu*) thisPtr)->Increm();
return NULL;
}
Devemu::~Devemu() {
pthread_cancel (thread_id);
}
Devemu::Devemu() {
VarInc = 0;
/// get default value of arrts
pthread_attr_init(&attr);
/// start thread
pthread_create(&thread_id, &attr, &Devemu::IncWrapper, this);
}
int Devemu::Var() {
return VarInc;
}
int main(int argc, char** argv) {
Devemu* em = new Devemu();
for(int i = 0 ; i < 100; i++) {
printf("%d\n", em->Var());
usleep (10);
}
delete em;
usleep (1000);
return (EXIT_SUCCESS);
}

Related

Trying to call a certain function each time

Okay, so I've an assignment with threads.I'm suppose to change the current running threads each period of time, let's say a second. First of all I've created a Thread class:
typedef unsigned long address_t;
#define JB_SP 6
#define JB_PC 7
#define STACK_SIZE (4096)
using namespace std;
class Thread{
public:
enum State{
BLOCKED,
READY,
RUNNING
};
Thread(int tid, void(*f)(void), int stack_size) :
tid(tid), stack_size(stack_size){
address_t sp, pc;
sp = (address_t)stack + STACK_SIZE - sizeof(address_t);
pc = (address_t)f;
sigsetjmp(env, 1);
(env->__jmpbuf)[JB_SP] = translate_address(sp);
(env->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&env->__saved_mask);
state = READY;
quantums = 0;
}
Thread (){}
address_t translate_address(address_t addr)
{
address_t ret;
asm volatile("xor %%fs:0x30,%0\n"
"rol $0x11,%0\n"
: "=g" (ret)
: "0" (addr));
return ret;
}
State get_state() const
{
return state;
}
void set_state(State state1)
{
state = state1;
}
int get_id() const
{
return tid;
}
pthread_t& get_thread()
{
return thread;
}
sigjmp_buf& get_env()
{
return env;
}
void raise_quantums()
{
quantums ++;
}
int get_quantums()
{
return quantums;
}
int add_to_sync(int tid)
{
sync.push_back(tid);
}
bool appear_in_sync_list(int tid)
{
return (find(sync.begin(), sync.end(), tid) != sync.end());
}
private:
vector<int> sync;
int quantums;
State state;
char stack[STACK_SIZE];
sigjmp_buf env;
pthread_t thread;
int tid;
int stack_size;
};
I've this function which changes threads:
void running_thread(int sigNum)
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigprocmask(SIG_SETMASK, &set, NULL);
total_quantum ++;
if (currentThread.get_state() == Thread::RUNNING)
{
Thread& t = ready_threads.back();
ready_threads.pop_back();
currentThread.set_state(Thread::READY);
ready_threads.push_back(currentThread);
sigsetjmp(currentThread.get_env(), 1);
currentThread = t;
t.raise_quantums();
siglongjmp(currentThread.get_env(), 1);
}
if (currentThread.get_state() == Thread::BLOCKED)
{
Thread &t = ready_threads.back();
ready_threads.pop_back();
currentThread.set_state(Thread::BLOCKED);
blocked_threads.push_back(currentThread);
sigsetjmp(currentThread.get_env(), 1);
currentThread = t;
t.raise_quantums();
siglongjmp(currentThread.get_env(), 1);
}
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigprocmask(SIG_UNBLOCK, &set, NULL);
}
It actually doesn't matter what it do, my problem is that it isn't even called.
My program first call this function:
int clock_set()
{
int seconds = quantum / SECOND;
int usecs = quantum - seconds*SECOND;
timer.it_value.tv_sec = seconds;
timer.it_value.tv_usec = usecs;
timer.it_interval.tv_sec = seconds;
timer.it_interval.tv_usec = usecs;
struct sigaction sa;
sa.sa_handler = &running_thread;
if (sigaction(SIGVTALRM, &sa,NULL) < 0) {
cerr << "system error: sigaction error.";
return FAILURE;
}
// Start a virtual timer. It counts down whenever this process is executing.
if (setitimer (ITIMER_VIRTUAL, &timer, NULL)) {
cerr << "system error: setitimer error.";
return FAILURE;
}
return SUCCESS;
}
Basically I was trying to make running_thread get activate each second, so I Was using sigaction and sa_handler.
This is my main function:
int main()
{
uthread_init(1000000) // Initiliaze variable 'quantum' to be a second, this function also calls clock_set
uthread_spawn(&g); // Creating a thread object with function g inserting it to ready_threads vector and to threads vector
uthread_spawn(&f); // creating a thread object with function f inserting it to ready_threads vector and to threads vector
}
The vector "ready_threads" has 2 threads in it.
Why doesn't it call running_thread?

C++11 Threads Not Joining

I have experience with threads in Java but want to learn how to use them in C++11. I tried to make a simple threadpool, where threads are created once and can be asked to execute tasks.
#include <thread>
#include <iostream>
#define NUM_THREADS 2
class Worker
{
public:
Worker(): m_running(false), m_hasData(false)
{
};
~Worker() {};
void execute()
{
m_running = true;
while(m_running)
{
if(m_hasData)
{
m_system();
}
m_hasData = false;
}
};
void stop()
{
m_running = false;
};
void setSystem(const std::function<void()>& system)
{
m_system = system;
m_hasData = true;
};
bool isIdle() const
{
return !m_hasData;
};
private:
bool m_running;
std::function<void()> m_system;
bool m_hasData;
};
class ThreadPool
{
public:
ThreadPool()
{
for(int i = 0; i < NUM_THREADS; ++i)
{
m_threads[i] = std::thread(&Worker::execute, &m_workers[i]);
}
};
~ThreadPool()
{
for(int i = 0; i < NUM_THREADS; ++i)
{
std::cout << "Stopping " << i << std::endl;
m_workers[i].stop();
m_threads[i].join();
}
};
void execute(const std::function<void()>& system)
{
// Finds the first non-idle worker - not really great but just for testing
for(int i = 0; i < NUM_THREADS; ++i)
{
if(m_workers[i].isIdle())
{
m_workers[i].setSystem(system);
return;
}
}
};
private:
Worker m_workers[NUM_THREADS];
std::thread m_threads[NUM_THREADS];
};
void print(void* in, void* out)
{
char** in_c = (char**)in;
printf("%s\n", *in_c);
}
int main(int argc, const char * argv[]) {
ThreadPool pool;
const char* test_c = "hello_world";
pool.execute([&]() { print(&test_c, nullptr); });
}
The output of this is:
hello_world
Stopping 0
After that, the main thread halts, because it's waiting for the first thread to join (in the destructor of the ThreadPool). For some reason, the m_running variable of the workers is not set to false, which keeps the application running indefinitely.
In Worker::stop the member m_running is written in the main thread, while it is read in execute in a different thread. This is undefined behavior. You need to protect read/write access from different threads. In this case I would recommend using std::atomic<bool> for m_running.
Edit: the same holds for m_hasData.

Embedding matplotlib in C++

I am reading a message from a socket with C++ code and am trying to plot it interactively with matplotlib, but it seems Python code will block the main thread, no matter I use show() or ion() and draw(). ion() and draw() won't block in Python.
Any idea how to plot interactively with matplotlib in C++ code?
An example would be really good.
Thanks a lot.
You may also try creating a new thread that does the call to the
blocking function, so that it does not block IO in your main program
loop. Use an array of thread objects and loop through to find an unused
one, create a thread to do the blocking calls, and have another thread
that joins them when they are completed.
This code is a quick slap-together I did to demonstrate what I mean about
using threads to get pseudo asynchronous behavior for blocking functions...
I have not compiled it or combed over it very well, it is simply to show
you how to accomplish this.
#include <pthread.h>
#include <sys/types.h>
#include <string>
#include <memory.h>
#include <malloc.h>
#define MAX_THREADS 256 // Make this as low as possible!
using namespace std;
pthread_t PTHREAD_NULL;
typedef string someTypeOrStruct;
class MyClass
{
typedef struct
{
int id;
MyClass *obj;
someTypeOrStruct input;
} thread_data;
void draw(); //Undefined in this example
bool getInput(someTypeOrStruct *); //Undefined in this example
int AsyncDraw(MyClass * obj, someTypeOrStruct &input);
static void * Joiner(MyClass * obj);
static void * DoDraw(thread_data *arg);
pthread_t thread[MAX_THREADS], JoinThread;
bool threadRunning[MAX_THREADS], StopJoinThread;
bool exitRequested;
public:
void Main();
};
bool MyClass::getInput(someTypeOrStruct *input)
{
}
void MyClass::Main()
{
exitRequested = false;
pthread_create( &JoinThread, NULL, (void *(*)(void *))MyClass::Joiner, this);
while(!exitRequested)
{
someTypeOrStruct tmpinput;
if(getInput(&tmpinput))
AsyncDraw(this, tmpinput);
}
if(JoinThread != PTHREAD_NULL)
{
StopJoinThread = true;
pthread_join(JoinThread, NULL);
}
}
void *MyClass::DoDraw(thread_data *arg)
{
if(arg == NULL) return NULL;
thread_data *data = (thread_data *) arg;
data->obj->threadRunning[data->id] = true;
// -> Do your draw here <- //
free(arg);
data->obj->threadRunning[data->id] = false; // Let the joinThread know we are done with this handle...
}
int MyClass::AsyncDraw(MyClass *obj, someTypeOrStruct &input)
{
int timeout = 10; // Adjust higher to make it try harder...
while(timeout)
{
for(int i = 0; i < MAX_THREADS; i++)
{
if(thread[i] == PTHREAD_NULL)
{
thread_data *data = (thread_data *)malloc(sizeof(thread_data));
if(data)
{
data->id = i;
data->obj = this;
data->input = input;
pthread_create( &(thread[i]), NULL,(void* (*)(void*))MyClass::DoDraw, (void *)&data);
return 1;
}
return 0;
}
}
timeout--;
}
}
void *MyClass::Joiner(MyClass * obj)
{
obj->StopJoinThread = false;
while(!obj->StopJoinThread)
{
for(int i = 0; i < MAX_THREADS; i++)
if(!obj->threadRunning[i] && obj->thread[i] != PTHREAD_NULL)
{
pthread_join(obj->thread[i], NULL);
obj->thread[i] = PTHREAD_NULL;
}
}
}
int main(int argc, char **argv)
{
MyClass base;
base.Main();
return 0;
}
This way you can continue accepting input while the draw is occurring.
~~Fixed so the above code actually compiles, make sure to add -lpthread

ReadWrite lock using Boost.Threads (how to convert this simple class)

I am porting some code from windows to Linux (Ubuntu 9.10). I have a simple class (please see below), which uses windows functions to implement simple mutex locking. I want to use Boost.Threads to reimplement this, but that library is new to me.
Can someone point out the changes I need to make to the class below, in order tomuse Boost.Threads instead of the WIN specific functions?
#ifndef __my_READWRITE_LOCK_Header__
#define __my_READWRITE_LOCK_Header__
#include <windows.h>
//Simple RW lock implementation is shown below.
#define RW_READERS_MAX 10
#define RW_MAX_SEMAPHORE_COUNT 10
#define RW_MUTEX_NAME L"mymutex"
#define RW_SEMAPHORE_NAME L"mysemaphore"
class CThreadRwLock
{
public:
CThreadRwLock()
{
InitializeCriticalSection(&m_cs);
m_hSem = CreateSemaphore(0, RW_READERS_MAX, RW_READERS_MAX, 0);
}
~CThreadRwLock()
{
DeleteCriticalSection(&m_cs);
CloseHandle(m_hSem);
}
void AcquireReaderLock()
{
EnterCriticalSection(&m_cs);
WaitForSingleObject(m_hSem, INFINITE);
LeaveCriticalSection(&m_cs);
}
void AcquireWriterLock()
{
EnterCriticalSection(&m_cs);
for(int i = 0; i < RW_READERS_MAX; i++)
{
WaitForSingleObject(m_hSem, INFINITE);
}
LeaveCriticalSection(&m_cs);
}
void ReleaseReaderLock()
{
ReleaseSemaphore(m_hSem, 1, 0);
}
void ReleaseWriterLock()
{
ReleaseSemaphore(m_hSem, RW_READERS_MAX, 0);
}
private:
CRITICAL_SECTION m_cs;
HANDLE m_hSem;
};
class CProcessRwLock
{
public:
CProcessRwLock()
{
m_h = CreateMutex(NULL, FALSE, RW_MUTEX_NAME);
m_hSem = CreateSemaphore(NULL, RW_MAX_SEMAPHORE_COUNT, RW_MAX_SEMAPHORE_COUNT, RW_SEMAPHORE_NAME);
}
~CProcessRwLock()
{
CloseHandle(m_h);
}
void AcquireReaderLock()
{
WaitForSingleObject(m_h, INFINITE);
ReleaseMutex(m_h);
}
void AcquireWriterLock()
{
WaitForSingleObject(m_h, INFINITE);
for(int i = 0; i < RW_READERS_MAX; i++)
{
WaitForSingleObject(m_hSem, INFINITE);
}
ReleaseMutex(m_h);
}
void ReleaseReaderLock()
{
ReleaseSemaphore(m_hSem, 1, 0);
}
void ReleaseWriterLock()
{
ReleaseSemaphore(m_hSem, RW_READERS_MAX, 0);
}
private:
HANDLE m_h, m_hSem;
};
class AutoThreadRwLock
{
public:
AutoThreadRwLock(const bool readlock = true):m_readlock(readlock)
{
if (readlock)
m_lock.AcquireReaderLock();
else
m_lock.AcquireWriterLock();
}
~AutoThreadRwLock()
{
if (m_readlock)
m_lock.ReleaseReaderLock();
else
m_lock.ReleaseWriterLock();
}
private:
AutoThreadRwLock(const AutoThreadRwLock&);
AutoThreadRwLock& operator= (const AutoThreadRwLock& );
CThreadRwLock m_lock ;
bool m_readlock ;
};
class AutoProcessRwLock
{
public:
AutoProcessRwLock(const bool readlock = true): m_readlock(readlock)
{
if (readlock)
m_lock.AcquireReaderLock();
else
m_lock.AcquireWriterLock();
}
~AutoProcessRwLock()
{
if (m_readlock)
m_lock.ReleaseReaderLock();
else
m_lock.ReleaseWriterLock();
}
private:
AutoProcessRwLock(const AutoProcessRwLock&);
AutoProcessRwLock& operator= (const AutoProcessRwLock&);
CProcessRwLock m_lock ;
bool m_readlock ;
};
#endif //__my_READWRITE_LOCK_Header__
I'm not going to re-write all your code for you. However you should look into boost's shared_mutex class.
Also, this question from StackOverflow shows how to use a boost::shared_mutex

pthread in a class

Hey everyone, considering the following code (compiled with g++ -lpthread thread_test.cpp) how can I know what number thread I am in from inside "thread_function"? And let me know if you have any other suggestions.
Thanks!
thread_test.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
class A {
public:
A();
void run();
private:
static void* thread_function( void *ptr );
pthread_t m_thread1, m_thread2;
static int m_global;
};
int A::m_global = 0;
A::A() {
int ret1 = pthread_create( &m_thread1, NULL, &A::thread_function, this );
int ret2 = pthread_create( &m_thread2, NULL, &A::thread_function, this );
}
void A::run() {
while ( 1 ) {
printf( "parent incrementing...\n" );
m_global++;
sleep( 2 );
}
}
void* A::thread_function( void *ptr ) {
printf( "I'm thread ?\n" );
while ( 1 ) {
printf("thread global: %d\n", m_global );
sleep( 1 );
}
}
int main() {
A a;
a.run();
return 0;
}
You can use pthread_self() function.
Well i figured out I could do this, but I'm not sure if making the pthread_t variables static is the best thing to do. Opinions?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
class A {
public:
A();
void run();
private:
static void* thread_function( void *ptr );
static pthread_t m_thread1, m_thread2;
static int m_global;
};
int A::m_global = 0;
pthread_t A::m_thread1 = 0;
pthread_t A::m_thread2 = 0;
A::A() {
int ret1 = pthread_create( &m_thread1, NULL, &A::thread_function, this );
int ret2 = pthread_create( &m_thread2, NULL, &A::thread_function, this );
}
void A::run() {
while ( 1 ) {
printf( "parent incrementing...\n" );
m_global++;
sleep( 2 );
}
}
void* A::thread_function( void *ptr ) {
int thread_num = 0;
if ( pthread_self() == m_thread1 ) {
thread_num = 1;
} else {
thread_num = 2;
}
printf( "I'm thread %d\n", thread_num );
while ( 1 ) {
printf("thread %d global: %d\n", thread_num, m_global );
sleep( 1 );
}
}
int main() {
A a;
a.run();
return 0;
}
The correct answer depends heavily on why you need this information. If the two threads are doing different things, why do they have the same start function?
One simple fix is this:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
class A {
public:
A();
void run();
private:
static void* thread_function( void *ptr, int which );
static void* thread_function_1( void *ptr );
static void* thread_function_2( void *ptr );
pthread_t m_thread1, m_thread2;
static int m_global;
};
int A::m_global = 0;
A::A() {
int ret1 = pthread_create( &m_thread1, NULL, &A::thread_function_1, this );
int ret2 = pthread_create( &m_thread2, NULL, &A::thread_function_2, this );
}
void A::run() {
while ( 1 ) {
printf( "parent incrementing...\n" );
m_global++;
sleep( 2 );
}
}
void* A::thread_function_1( void *ptr ) { thread_function(ptr, 1); }
void* A::thread_function_2( void *ptr ) { thread_function(ptr, 2); }
void* A::thread_function( void *ptr, int which ) {
printf( "I'm thread %d\n", which );
while ( 1 ) {
printf("thread global: %d\n", m_global );
sleep( 1 );
}
}
int main() {
A a;
a.run();
return 0;
}
If you have more than 2 threads, you can use another approach. Create a structure that holds all the information the thread needs, including the this pointer and which thread it is. Allocate a structure of that type, stuff it with everything the thread needs and pass that to the thread through the pthread_create function instead of just the this pointer.