multiple threads-not able to access class member variables set by constructor - c++

I am spawning threads from one of the functions called by main.
The start routine of this thread is a function in another separate class altogether. So to get access to that class, i have written an extern "C" function, by which i am able to call the start routine.
But the problem is, after getting to the start routine, the thread is not able to access the member variables value set by the constructor of the Class.
This seems strange to me as everything is perfect when i am running the code without using threads.
Can someone please suggest me what would be going wrong?
I am posting some relevant code details below:
`extern "C"{
void* run(void* arg)
{
CFileOp* trans = static_cast<CFileOp*>(arg);
trans->write_block(arg);
return 0;
}
}
int
TestFileOps(int file_size, CGlobalItems &globals){
...
for(i = 0; i < num_chunks; i++)
{
pthread_create( &thread_id[i], NULL, run, buf);
}
...
}`
//there is a class CFileOp which has some private member variables and write_block is a public function of it.
void* CFileOp::write_block(PVOID buf)
{
int rc = my_write(78, buf, m_chunk_size);
if(rc != m_chunk_size)
{
fprintf(stderr, "Can't write block; rc=%d, buf=%p, chunk_size=%d\n", rc, buf, m_chunk_size);
pthread_exit((void *)-1);return 0;;
}
m_cur_pos++;
fprintf(stderr,"m_cur_pos: %d m_chunks_per_file: %d\t",m_cur_pos,m_chunks_per_file);
if(m_cur_pos >= m_chunks_per_file)
{
if(seek(0, SEEK_CUR) == -1)
pthread_exit((void *)-1);return 0;// return -1;
}
pthread_exit((void *)rc);
return 0;
}
I can't post the whole code as its a benchmark code and is very long and detailed.
Please help.

If I understand the question properly you want to call a member function from a thread, you can just do if you have c++11
std::thread th(&my_class::my_mem_func, &my_object);
this will create a thread th and execute the my_mem_func of my_object
EDIT
std::thread th(&my_writer::write_some, &writer_object, data);
th.join();

Related

How to Synchronize function calls with callbacks?

I am using a SDK that provides some functions and one callback to send the results. Code is in C++.
SDK APIs:
typedef void(*onSdkCallBackFn)(int cmdType, const char *jsonResult);
void SetCallback(onSdkIotCallBackFn Fn);
void SetCommand(int commandId);
There is no return value for SetCommand, so need to wait for SDK to send the result through callback.
I need to provide my own API for upper layer, but they expect to get the result by function call and do not intend to receive it through callback.
here is my sample code:
void MyCallback(int cmdType, const char *jsonResult)
{
int result;
if (cmfType == 5)
result = 100;
else
result = 0;
}
int DoCommandNo5()
{
int result = -1; // need to be updated in callback function
etCallback(&MyCallback);
DoCommand(5);
// here I need to wait for result through SDK callback and return it.
// How to handle it?
return result;
}
Can I do this without using threads? What is the best way to handle this task?
I checked these approaches: WaitForSingleObject and std::condition_variable but seems for both need create separate thread.
Any advise and help is appreciated.
Well one way to do it is to e.g. wait on std::condition_variable:
int DoCommandNo5()
{
int result = -1;
bool resultReady = false;
std::mutex m;
std::unique_lock<std::mutex> lk(m);
std::condition_variable cv;
auto getResult = [&](int commandResult) {
resultReady = true;
result = commandResult;
cv.notify_one();
};
setCallback(getResult);
doCommand(5);
cv.wait(lk, [&]{return resultReady;});
return result;
}
You can also call cv.wait_for method so DoCommandNo5 function doesn't block infinitely.
Since the details are vague, I will answer from a very general perspective of how to wrap an event driven based functionality into a standard function.
I expect result to be accessible globally or passed somehow to the callback function. Therefore, in the function expecting the callback to set an actual result, one can just do waiting while loop. e.g.:
int result;
void TheCallback() {
...
result = 255;
...
}
int TheCallbackWrapper() {
...
result = -1; // let's assume -1 means result is not yet set
while (result == -1) {
sleep(1); // an assumption of system call to sleep the execution for 1 ms, just not to eat CPU time too much
}
return result; // if we reach this point, then the callback has set a result ready to be returned
}

Capture value from infinite thread c++

I have created a thread that is running parrallel with main thread. Both threads are doing something infinitely (both have while(true) statement). Main thread while(true) is creating game logic in frames, and second thread is receiveing messages from socket.
Is it possible to get string value of message received from second thread into main thread each frame without returning from second thread?
In c#, I would do it with method invoker but I didn't find anything helpful for c++. Is it possible to perform in c++?
Function which creates thread:
void ReceiveMessage() {
//std::promise<int> p;
//auto f = p.get_future();
char buf[1024];
string usernput;
int bytesReceived = 0;
std::thread receiveMessage(&FactoredThread::ThreadFunction, *this);
receiveMessage.detach();
//pokusajporuke = f.get();
}
ThreadFunction:
void ThreadFunction() {
bytesReceived = 0;
while (true) {
bytesReceived = recv(sock, buf, 1024, 0);
if (bytesReceived > 0) {
string primljeniString = "";
for (int i = 0; i < sizeof(buf); i++) {
if (buf[i] != 0)
{
primljeniString += buf[i];
}
}
ZeroMemory(buf, 1024);
pokusajporuke = primljeniString;
}
}
}
So how to get "pokusajporuke" string for main thread?
Yes, sure. There are many ways of solving this problem.
One way is to use signals and slots, like in Qt. For pure C++ you could use Boost.Signals2, which is thread safe.
Or you can realize pattern producer-consumer. One thread(producer) puts values into buffer(it should be thread-safe buffer), second takes them from there.
I think, for your problem second way is better.
Actually what I needed was global static variable. And then with another method from main thread I put that global variable into class property

Returning code from pthread creation in C++ is 11

I have thread creation problem using Pthread. My code is as follows. I show only some portion due to space constraints.
Main.c create Detectdirection instance and send to the function.
d = new Detectdirection();
while(run)
{
int ret = d->run_parallel(d);
if(ret == -1)
run = false;
}
My Detectdirection Class has two functions to run in parallel:
class Detectdirection{
public:
int run_parallel(void*p);
void *Tracking(void *p);
static void *Tracking_helper(void * p);
void *ReadImage(void *p );
static void *ReadImage_helper(void *p );
private:
pthread_t thread[2];
}
void *Detectdirection::ReadImage(void *p){
Detectdirection *app = (Detectdirection*)p;
while(run){
}
pthread_exit(NULL);
}
void *Detectdirection::Tracking(void *p){
Detectdirection *app = (Detectdirection*)p;
while(run){
}
pthread_exit(NULL);
}
void *Detectdirection::Tracking_helper(void *p){
Detectdirection *app = (Detectdirection*)p;
return ((Detectdirection*)p)->Tracking(app);
}
void *Detectdirection::ReadImage_helper(void *p ){
Detectdirection *app = (Detectdirection*)p;
return ((Detectdirection*)p)->ReadImage(app);
}
int Detectdirection::run_parallel(void* p){
Detectdirection *app = (Detectdirection*)p;
int rc = pthread_create(&thread[0], NULL, app->ReadImage_helper, app);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
return -1;
}
rc = pthread_create(&thread[1], NULL, app->Tracking_helper, app);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
return -1;
}
return 0;
}
Compile is ok and when I run, I have thread creation error. That sort of return type 11 happens only when many threads are created. But now I create only two thread and I have that error. What could be wrong?
I believe your are getting EAGAIN (based on the error code 11). That (obivously) means your system doesn't have enough resources to create threads anymore.
POSIX documentation says:
[EAGAIN] The system lacked the necessary resources to create another
thread, or the system-imposed limit on the total number of threads in
a process {PTHREAD_THREADS_MAX} would be exceeded.
I am not quite sure the following is true.
But now I create only two thread and I have that error. What could be wrong?
Here,
while(run)
{
int ret = d->run_parallel(d);
if(ret == -1)
run = false;
}
You are creating in a loop and each call d->run_parallel() creates two threads. So, you are potentially creating infinite number of threads
as the loop only breaks when pthread_create() fails. So, you may want to look at this loop carefully whether you really want to do as it is right now.
You don't seem to join with the threads you create. So, you could detach the threads so that thread-specific resources are released immediately when the thread(s) exit.
You can do:
pthread_detach(pthread_self());
in both ReadImage_helper() and Tracking_helper() functions to detach them. This could potentially solve your resource issue.
If it's still present then you have to look at ways to limit the number of threads that are simultaneously running on your system. One possible option is to use thread pools -- create a fixed number of threads and assign them new tasks as the threads complete their current task(s).

Changing program execution flow by signal and return address

I'm trying to change program execution flow by changing return address of functions in this code:
void s(int signum) {
int b = 1;
*(&b+3) = *(&b+3) + 4;
}
void f() {
while(true);
printf("f exit\n");
}
int main() {
signal( SIGCONT, s );
f();
printf("end of prog");
return 0;
}
For this purpose I invoke f function. So it gets stuck at while(true). Then I send a SIGCONT signal to program using kill -SIGCONT <PID> command. Now the program must interrupt executing while(true) in f and execute s function. In s function I defined b to find return address of s function in runtime stack which is *(&b+3). I try to change this value with *(&b+3) = *(&b+3) + 4 so that when it gets back to f, skip execution of while(true) and execute printf("f exit\n"). but it keeps getting stuck at while and I have no idea how to make this work.
NOTE: I verified *(&b+3) as return address by comparing it to value returned by __builtin_return_address(0) before.
Body of functions main and f must be unchanged.
Thanks.
The solution is tell somehow the while loop that something changed.
For example
volatile int flag = 0 ;
void s(int signum) {
int b = 1;
__sync_fetch_and_add( &flag, 1 ) ;
}
void f() {
while(__sync_fetch_and_add( &flag, 0 ) == 0);
printf("f exit\n");
}
The atomic intrinsic (function __sync_fetch_and_add) is added to avoid having the loop optimized away. I am not sure a simple volatile is enough. Waiting for comments myself on this....

global static boolean pointer causes segmentation fault using pthread

New to pthread programming, and stuck on this error when working on a C++&C mixed code.
What I have done is to call the c code in the thread created by the c++ code. There is a static boolean pointer is_center used in the thread and should got free when the thread finishes.
However I noticed that every time when the program processed into the c function, the value of the boolean pointer would be changed and the segmentation fault then happened due to the free(). And the problem only happens when the c code is used. Remove the c code and the multi-thread c++ part works well.
Detail code is as follows:
static bool *is_center;
// omit other codes in between ...
void streamCluster( PStream* stream)
{
// some code here ...
while(1){
// some code here ...
is_center = (bool*)calloc(points.num,sizeof(bool));
// start the parallel thread here.
// the c code is invoked in this function.
localSearch(&points,kmin, kmax,&kfinal); // parallel
free(is_center);
}
And the function using parallel is as follows (my c code is invoked in each thread):
void localSearch( Points* points, long kmin, long kmax, long* kfinal ) {
pthread_barrier_t barrier;
pthread_t* threads = new pthread_t[nproc];
pkmedian_arg_t* arg = new pkmedian_arg_t[nproc];
pthread_barrier_init(&barrier,NULL,nproc);
for( int i = 0; i < nproc; i++ ) {
arg[i].points = points;
arg[i].kmin = kmin;
arg[i].kmax = kmax;
arg[i].pid = i;
arg[i].kfinal = kfinal;
arg[i].barrier = &barrier;
pthread_create(threads+i,NULL,localSearchSub,(void*)&arg[i]);
}
for ( int i = 0; i < nproc; i++) {
pthread_join(threads[i],NULL);
}
delete[] threads;
delete[] arg;
pthread_barrier_destroy(&barrier);
}
Finally the function calling my c code:
void* localSearchSub(void* arg_) {
int eventSet = PAPI_NULL;
begin_papi_thread(&eventSet);
pkmedian_arg_t* arg= (pkmedian_arg_t*)arg_;
pkmedian(arg->points,arg->kmin,arg->kmax,arg->kfinal,arg->pid,arg->barrier);
end_papi_thread(&eventSet);
return NULL;
}
And from gdb, what I have got for the is_center is:
Breakpoint 2, localSearchSub (arg_=0x600000000000bc40) at streamcluster.cpp:1711
1711 end_papi_thread(&eventSet);
(gdb) s
Hardware watchpoint 1: is_center
Old value = (bool *) 0x600000000000bba0
New value = (bool *) 0xa93f3
0x400000000000d8d1 in localSearchSub (arg_=0x600000000000bc40) at streamcluster.cpp:1711
1711 end_papi_thread(&eventSet);
Any suggestions? Thanks in advance!
Some new information about the code: for the c code, I am using the PAPI package. I write my own papi wrapper to initialize and read system counters. The code is as follows:
void begin_papi_thread(int* eventSet)
{
int thread_id = pthread_self();
// Events
if (PAPI_create_eventset(eventSet)) {
PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);
printf("*** ERROR *** Failed to create event set for thread %d: %s\n.", thread_id, error_string);
}
if((return_value = PAPI_add_events(*eventSet, event_code, event_num)) != PAPI_OK)
{
printf("*** ERROR *** Failed to add event for thread %d: %d.\n", thread_id, return_value);
}
// Start counting
if ((return_value = PAPI_start(*eventSet)) != PAPI_OK) {
PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);
printf("*** ERROR *** PAPI failed to start the event for thread %d: %s.\n", thread_id, error_string);
}
}
void end_papi_thread(int* eventSet)
{
int thread_id = pthread_self();
int i;
long long * count_values = (long long*)malloc(sizeof(long long) * event_num);
if (PAPI_read(*eventSet, count_values) != PAPI_OK)
printf("*** ERROR *** Failed to load count values.\n");
if (PAPI_stop(*eventSet, &dummy_values) != PAPI_OK) {
PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);
printf("*** ERROR *** PAPI failed to stop the event for thread %d: %s.\n", thread_id, error_string);
return;
}
if(PAPI_cleanup_eventset(*eventSet) != PAPI_OK)
printf("*** ERROR *** Clean up failed for the thread %d.\n", thread_id);
}
I don't think you've posted enough code to really understand your problem, but it looks suspicious that you've declared is_center global. I assume you're using it in more than one place, possibly by multiple threads (localSearchSub mentions it, which is your worker thread function).
If is_center is being read or written by multiple threads, you probably want to protect it with a pthread mutex. You say it is "freed when the thread finishes", but you should be aware that there are nprocs threads, and it looks like they're all working on an array of is_center[points] bools. If points != nproc, this could b e a bad thing[1]. Each thread should probably work on its own array, and localSearch should aggregate the results.
The xxx_papi_thread functions don't get any hits on Google, so I can only imagine it's your own... unlikely we'll be able to help you, if the problem is in there :)
[1]: Even if points == nproc, it is not necessarily OK to write to different elements of an array from multiple threads (it's compiler and processor dependent). Be safe, use a mutex.
Also, this is tagged C++. Can you replace the calloc and dynamic arrays (using new) with vectors? It might end up easier to debug, and it certainly ends up easier to maintain. Why do you hate and want to punish the readers of your code? ;)