Using a class function in int main() - c++

I am having problems calling my functions from my main program.
These functions HAVE to be in my class.
How do I access them from my int main()?
#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <semaphore.h>
#include <synch.h>
using namespace std;
class myCountingSemaphoreUsingBinarySemaphore {
public:
void waitSemaphore(pthread_mutex_t *thread)
{
pthread_mutex_lock(*thread);// Makes value 1 (Not Available)
}
void signalSemaphore(pthread_mutex_t *thread)
{
pthread_mutex_unlock(*thread); // Makes value 0 (Available)
}
void deleteSemaphore(pthread_mutex_t *thread)
{
pthread_mutex_destroy(*thread);// Deletes
}
};
int readerCount;
int database = (rand() / 100); // Number less than 1000
void reader_writer(void);
int main(int argc, char *argv[])
{
myCountingSemaphoreUsingBinarySemaphore obj;
pthread_mutex_t mutex1;
pthread_mutex_t wrt;
pthread_create( &mutex1, NULL, reader_writer, void);
pthread_create( &wrt, NULL, reader_writer, void);
//----------------------READER------------------------//
do{
cout << "Database Before Read = " << database << endl;
obj.waitSemaphore(mutex1);//lock
readerCount++;
if (readerCount == 1)
{
obj.waitSemaphore(wrt);//lock
obj.signalSemaphore(mutex1);//unlock
//reading is preformed
obj.waitSemaphore(mutex1); // lock
readerCount--;
}
if(readerCount == 0)
{
obj.signalSemaphore(wrt);//unlock
obj.signalSemaphore(mutex1); // unlock
}
cout << "Database After Read = " << database << endl;
}while (true);
//-----------------------WRITER---------------------//
do{
cout << "Database Before Write = " << database << endl;
obj.waitSemaphore(wrt);//lock
//writing is preformed
database = database + 10;
obj.signalSemaphore(mutex1);//unlock
cout << "Database After Write = " << database << endl;
}while(true);
pthread_join( mutex1, NULL);
pthread_join( wrt, NULL);
obj.deleteSemaphore(* mutex1);
obj.deleteSemaphore(* wrt);
return 0;
}
void reader_writer () {}
Here is an error I get:
what type do they need to be? pthread_mutex_t_create? or pthread_t_create?
what is the proper type?

Functions inside a class are called methods. You need to instantiate an object of that class to be able to use it's methods:
myCountingSemaphoreUsingBinarySemaphore obj; // obj is an instance of the class
obj.waitSemaphore(&mutex1);
obj.signalSemaphore(&mutex1);
EDIT:
By the way, pthread_create and pthread_join take a pthread_t* and not a mutex!
int pthread_create(pthread_t* thread,
pthread_attr_t* attr,
void* (*start_routine)(void*),
void* arg);

You can either declare those methods as static or use an object to make the calls:
myCountingSemaphoreUsingBinarySemaphore s;
s.waitSemaphore(wrt);

You are calling class methods as just waitSemaphore without creating the object of myCountingSemaphoreUsingBinarySemaphore.
You should create the object first.
myCountingSemaphoreUsingBinarySemaphore obj;
obj.waitSemaphore(mutex1);

The two threads you create (via reader_writer()) do nothing. main() just goes into the first do loop with no way of getting out.
Also, you seem to have confused mutex, semaphores, and condition variables. The function names makes it look like you're trying to implement condition variables in your class. But you're building it as just wrappers to mutex locks.
And finally, you are calling pthread_mutex_lock() et al. on a pthread_t when those functions are supposed to be called on a pthread_mutex_t.
There probably are other errors, but these are the ones that really jump out. Basically, you need to review multi-threaded programming, both in terms of how threads are created, and how they are synchronized.

You need to create an instance of the class (an object) in order to call his member functions.
In this particular code the member functions has no reason to be instance and could be static:
class foo{
public:
static void bar(int val)
{
//do something
}
};
int main()
{
foo::bar(10);
}

karlphillip was right, you need to pass by pointer instead of reference
BTW, following line are mistake also, the pthread_create accept and pthread_t instead of pthread_mutex_t
pthread_create( &mutex1, NULL, reader_writer, void);
pthread_create( &wrt, NULL, reader_writer, void);

Related

segmentation fault while using pthreads in class

I have the follwing code that gets core dumped error. Each C instance creates their own thread then runs. I guess there is something wrong with static function and class argument "count". When I comment out the code that prints it, no fault occurs..
#include <iostream>
#include <pthread.h>
using namespace std;
class C {
public:
int count;
C(int c_): count(c_){}
public:
void *hello(void)
{
std::cout << "Hello, world!" <<std::endl;
std::cout<<count; // bug here!!!
return 0;
}
static void *hello_helper(void *context)
{
return ((C *)context)->hello();
}
void run() {
pthread_t t;
pthread_create(&t, NULL, &C::hello_helper, NULL);
}
};
int main() {
C c(2);
c.run();
C c2(4);
c2.run();
while(true);
return 0;
}
Decided to write an answer. You were calling hello_helper with a context of NULL based on how you were creating your thread. C++ fully allows you to call member functions on null pointers, and no error occurs unless a member element is accessed.
In your case, by adding the line to print count. You are now accessing a member variable on a null pointer, which is a big no-no.
Here's an example of what you were getting away with:
#include <iostream>
class Rebel
{
public:
void speak()
{
std::cout << "I DO WHAT I WANT!" << std::endl;
}
};
int main()
{
void * bad_bad_ptr = NULL;
((Rebel*)bad_bad_ptr)->speak();
}
Output:
I DO WHAT I WANT!
By modifying your pthread_create call to pass the this pointer (i.e. pthread_create(&t, NULL, &C::hello_helper, this);, you now have a valid instance to access member variables on.
I solved the problem by passing this pointer instead off NULL while creating threads. I guess os created same thread twice int the former case ?

Pthread for C++ class functions which uses refrence to class object

I have a such a requirement that:-
1) There are two class, say Wrapper and Wrapper2.
2) Wrapper2 contains reference object of class Wrapper.
3) A thread will write data to a variable of class Wrapper which should be essentially be calling a member function of Wrapper.
4) Another thread can read and write data to class member of Wrapper and this thread essentially be called through Wrapper2.
Based on some answers on older question on Stackoverflow, i created an example code to check why my production code is failing and i am not able to figure out the problem. As soon as thread2 is created it receives SIGSEG signals. Code is below:-
#include <thread>
#include <iostream>
#include <chrono>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <wait.h>
#include <string.h>
pthread_mutex_t mt1;
void thread_signal(int signum)
{
pthread_exit(0);
}
void sig_func(int sig)
{
write(1, "Caught signal 11\n", 17);
std::cout<<"Caught signal :"<<sig<<std::endl;
signal(SIGSEGV,sig_func);
thread_signal(sig);
}
class Wrapper {
public:
Wrapper():i(10)
{
std::cout<<"Wrapper Constructor Called. "<<this<<" \n";
}
~Wrapper()
{
std::cout<<"Wrapper Destructor Called. "<<this<<"\n";
}
void member1() {
std::cout << "i am member1" << std::endl;
}
void member2(const char *arg1, unsigned arg2) {
std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
}
void setI(int i)
{
pthread_mutex_lock(&mt1);
this->i=i;
std::cout<<"set: "<< this->i<<std::endl;
pthread_mutex_unlock(&mt1);
}
int getI()
{
pthread_mutex_lock(&mt1);
std::cout<<"get: "<< this->i<<std::endl;
pthread_mutex_unlock(&mt1);
return 0;
}
int i;
};
class Wrapper2
{
public:
Wrapper2(Wrapper & wp):wp2(wp)
{
std::cout<<"Wrapper2 Constructor Called. "<<this<<" \n";
}
~Wrapper2()
{
std::cout<<"Wrapper2 Destructor Called. "<<this<<" \n";
}
Wrapper & wp2;
};
struct ThreadWrapper {
Wrapper & wr1;
Wrapper2 & wr2;
ThreadWrapper( Wrapper & wr1,Wrapper2& wr2):
wr1(wr1),wr2(wr2)
{
}
};
extern "C" void* wrapper1Fun ( void* wr1)
{
std::auto_ptr< Wrapper > wrp1 ( static_cast< Wrapper* >( wr1 ) );
std::cout<<"Thread 1 created. \n";
while(1)
{
wrp1->setI(rand()%100);
usleep(50);
}
return 0;
}
extern "C" void* wrapper2Fun ( void* wr2)
{
std::auto_ptr< Wrapper2 > wrp2 ( static_cast< Wrapper2* >( wr2 ) );
std::cout<<"Thread 2 created. \n";
while(1)
{
wrp2->wp2.getI();
usleep(50);
}
return 0;
}
int main(int argc, char **argv) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = thread_signal;
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, 0);
bool mainRunning= true;
Wrapper w;
Wrapper2 w1(w);
sleep(1);
ThreadWrapper * myWrap = new ThreadWrapper(w,w1);
sleep(1);
pthread_t pt1;
pthread_t pt2;
pthread_attr_t attr;
signal(SIGSEGV,sig_func); // Register signal handler before going multithread
pthread_attr_init(&attr);
int i = pthread_create(&pt1, NULL,wrapper1Fun, myWrap);
std::cout<<"First thread status "<<i<<std::endl;
sleep(1);
int j = pthread_create(&pt2, &attr,wrapper2Fun, myWrap);
std::cout<<"Second thread status "<<j<<std::endl;
sleep(1);
while(1);
fprintf(stderr, "kill thread\n");
//pthread_kill(pt1, SIGTERM);
fprintf(stderr, "join thread\n");
pthread_join(pt1, NULL);
pthread_join(pt1, NULL);
return 0;
}
wrapper1Fun expects to be passed a pointer to a Wrapper, and wrapper2Fun expects to be passed a pointer to a Wraper2. But you're actually passing a pointer to a ThreadWrapper to each, which is a completely different type, so it goes wrong.
The use of void * and casts prevents the compiler from pointing out your type error. I would suggest using a type safe C++ threading library rather than raw pthread. Boost has one, as does the standard library from C++11.
Also your use of auto_ptr is questionable at best. It's deprecated, easy to get wrong, and a poor way of expressing ownership - prefer unique_ptr or shared_ptr.
Here you construct two auto_ptr values owning the same pointer, so it will be freed twice, which is undefined behaviour.
In any case there's no obvious reason to put any of these objects on the heap. If you do, you need to decide where the ownership of the memory resides.

Is it right to use mutex in the way used in this program?

I am new to C++, and I have started doing multi-threading in C++. Can you please comment on the following program? Is it a right way of using mutex? The other question is to identify the shared resource in C++ is easy - just look at static members. C++ doesn't have the concept of global variables, and therefore we can just look at the static members of a class? Afterwards, decide what should be serialized - mutex locked/unlocked? In C, it is a bit challenge to identify the shared resources, as there is a concept of global variables. Can you correct me on my understanding?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
/** get pid **/
#include <sys/types.h>
#include <unistd.h>
using namespace std;
class helium_thread
{
private:
pthread_t *thread_id;
public:
static pthread_mutex_t mutex_thread;
void set_thread_id(pthread_t tid);
pthread_t *get_thread_id();
int create_thread(pthread_t *thread_ptr, const pthread_attr_t *attr, void * (*start_routine)(void *), void *arg );
helium_thread();
~helium_thread();
};
void helium_thread::set_thread_id( pthread_t tid)
{
*(this->thread_id) = tid;
}
pthread_t * helium_thread::get_thread_id( )
{
return (this->thread_id);
}
int helium_thread::create_thread(pthread_t *thread_ptr, const pthread_attr_t *attr, void * (*start_routine)(void *), void *arg )
{
int ret;
ret = pthread_create(thread_ptr,attr,start_routine,(void *)arg) ;
cout<<"Thread created "<<std::hex<<thread_ptr<<endl;
return ret;
}
helium_thread::helium_thread()
{
thread_id = new pthread_t;
cout<<"Constructor called "<<std::hex<<thread_id<<endl;
}
helium_thread::~helium_thread()
{
cout<<"Destructor called"<<std::hex<<thread_id<<endl;
delete thread_id;
}
/** While defining the methods of the class, Keywords static and virtual should not be repeated in the definition. **/
/** They should only be used in the class declaration. **/
void *Thread_Function(void *thread_arg)
{
pthread_mutex_lock(&(helium_thread::mutex_thread));
cout<<"Inside Thread_Function"<<endl;
pid_t *thread_pid_val = (pid_t *) thread_arg;
/** std::hex will print the value isn hexadecimal **/
cout<<"The process pid is "<< std::hex << (*thread_pid_val) <<endl;
pthread_t ptid = pthread_self();
cout<<" The thread id is " << std::hex<< ptid << endl;
pthread_mutex_unlock(&(helium_thread::mutex_thread));
}
/** The definition of the static member can't be inside a function, You need to put it outside **/
/** When I tried using inside a function, I got the error - error: invalid use of qualified-name ‘helium_thread::mutex_thread **/
pthread_mutex_t helium_thread::mutex_thread = PTHREAD_MUTEX_INITIALIZER;
int main(int argc, char *argv[])
{
helium_thread thread_1, thread_2;
pid_t thread_pid_val = getpid();
pthread_t thread_1_id;
thread_1.create_thread((thread_1.get_thread_id()),NULL,Thread_Function,&thread_pid_val);
thread_2.create_thread((thread_2.get_thread_id()),NULL,Thread_Function,&thread_pid_val);
pthread_join( *(thread_1.get_thread_id()), NULL);
pthread_join( *(thread_2.get_thread_id()), NULL);
return 0;
}
A few things:
Globals can be used in C++ but try to avoid them, especially in multithreaded code.
You didn't initialize or destroy the mutex anywhere.
In C++ you should not call mutex_lock/unlock directly but have a wrapper class do it for you, to avoid keeping the mutex locked on an early return from the function (return on error or exception).
Example:
class auto_lock {
pthread_mutex_t* mutex;
public:
auto_lock(pthread_mutex_t* _mutex) : mutex(_mutex) {
if (mutex) pthread_mutex_lock(mutex);
}
~auto_lock(){
if (mutex) pthread_mutex_unlock(mutex);
}
};

Creating a thread in another class

I am trying to create a thread in the main function for the function named thefunction() in the ThreadMe class. The tricky part is that I need to start a thread in another class TYIA -Roland
#include <iostream>
#include <process.h>
#include <windows.h>
int main() {
char cincatcher[24];
std::cout << "I want to run a thread using a function on another class\n";
// Here is a good place to start the thread
while( true ) {
std::cin >> cincatcher
}
}
class ThreadMe {
void thefunction();
};
void ThreadMe::thefunction() {
while( true ) {
std::cout << "working!\n"
Sleep(800);
}
}
You cannot start thread directly with a class method. You must wrap the class method into a normal function, then start thread with the function. Like the following:
void threadBody(void *p) {
ThreadME tm;
tm.thefunction();
}

pthread_mutex_lock/unlock help [duplicate]

I am having problems calling my functions from my main program.
These functions HAVE to be in my class.
How do I access them from my int main()?
#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <semaphore.h>
#include <synch.h>
using namespace std;
class myCountingSemaphoreUsingBinarySemaphore {
public:
void waitSemaphore(pthread_mutex_t *thread)
{
pthread_mutex_lock(*thread);// Makes value 1 (Not Available)
}
void signalSemaphore(pthread_mutex_t *thread)
{
pthread_mutex_unlock(*thread); // Makes value 0 (Available)
}
void deleteSemaphore(pthread_mutex_t *thread)
{
pthread_mutex_destroy(*thread);// Deletes
}
};
int readerCount;
int database = (rand() / 100); // Number less than 1000
void reader_writer(void);
int main(int argc, char *argv[])
{
myCountingSemaphoreUsingBinarySemaphore obj;
pthread_mutex_t mutex1;
pthread_mutex_t wrt;
pthread_create( &mutex1, NULL, reader_writer, void);
pthread_create( &wrt, NULL, reader_writer, void);
//----------------------READER------------------------//
do{
cout << "Database Before Read = " << database << endl;
obj.waitSemaphore(mutex1);//lock
readerCount++;
if (readerCount == 1)
{
obj.waitSemaphore(wrt);//lock
obj.signalSemaphore(mutex1);//unlock
//reading is preformed
obj.waitSemaphore(mutex1); // lock
readerCount--;
}
if(readerCount == 0)
{
obj.signalSemaphore(wrt);//unlock
obj.signalSemaphore(mutex1); // unlock
}
cout << "Database After Read = " << database << endl;
}while (true);
//-----------------------WRITER---------------------//
do{
cout << "Database Before Write = " << database << endl;
obj.waitSemaphore(wrt);//lock
//writing is preformed
database = database + 10;
obj.signalSemaphore(mutex1);//unlock
cout << "Database After Write = " << database << endl;
}while(true);
pthread_join( mutex1, NULL);
pthread_join( wrt, NULL);
obj.deleteSemaphore(* mutex1);
obj.deleteSemaphore(* wrt);
return 0;
}
void reader_writer () {}
Here is an error I get:
what type do they need to be? pthread_mutex_t_create? or pthread_t_create?
what is the proper type?
Functions inside a class are called methods. You need to instantiate an object of that class to be able to use it's methods:
myCountingSemaphoreUsingBinarySemaphore obj; // obj is an instance of the class
obj.waitSemaphore(&mutex1);
obj.signalSemaphore(&mutex1);
EDIT:
By the way, pthread_create and pthread_join take a pthread_t* and not a mutex!
int pthread_create(pthread_t* thread,
pthread_attr_t* attr,
void* (*start_routine)(void*),
void* arg);
You can either declare those methods as static or use an object to make the calls:
myCountingSemaphoreUsingBinarySemaphore s;
s.waitSemaphore(wrt);
You are calling class methods as just waitSemaphore without creating the object of myCountingSemaphoreUsingBinarySemaphore.
You should create the object first.
myCountingSemaphoreUsingBinarySemaphore obj;
obj.waitSemaphore(mutex1);
The two threads you create (via reader_writer()) do nothing. main() just goes into the first do loop with no way of getting out.
Also, you seem to have confused mutex, semaphores, and condition variables. The function names makes it look like you're trying to implement condition variables in your class. But you're building it as just wrappers to mutex locks.
And finally, you are calling pthread_mutex_lock() et al. on a pthread_t when those functions are supposed to be called on a pthread_mutex_t.
There probably are other errors, but these are the ones that really jump out. Basically, you need to review multi-threaded programming, both in terms of how threads are created, and how they are synchronized.
You need to create an instance of the class (an object) in order to call his member functions.
In this particular code the member functions has no reason to be instance and could be static:
class foo{
public:
static void bar(int val)
{
//do something
}
};
int main()
{
foo::bar(10);
}
karlphillip was right, you need to pass by pointer instead of reference
BTW, following line are mistake also, the pthread_create accept and pthread_t instead of pthread_mutex_t
pthread_create( &mutex1, NULL, reader_writer, void);
pthread_create( &wrt, NULL, reader_writer, void);