How to initialized pthread_t variable in class constructor - c++

How to initialized pthread_t variable in class constructor.
C++ Static Analysis(coverity) Error: Non-static class member threadId is not initialized in this constructor nor in any functions that it calls.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
void *
threadFunc(void * arg)
{
std::cout << "Thread Function :: Start" << std::endl;
// Sleep for 2 seconds
sleep(2);
std::cout << "Thread Function :: End" << std::endl;
return NULL;
}
class threads
{
private:
pthread_t threadId;
int err;
public:
threads():err(0){};
~threads(){};
void create_thread();
void join_thread();
};
void
threads::create_thread()
{
// Create a thread that will function threadFunc()
err = pthread_create(&threadId, NULL, &threadFunc, NULL);
// Check if thread is created sucessfuly
if (err)
{
std::cout << "Thread creation failed : " << strerror(err);
}
else
{
std::cout << "Thread Created with ID : " << threadId << std::endl;
}
}
void
threads::join_thread()
{
err = pthread_join(threadId, NULL);
// check if joining is sucessful
if (err)
{
std::cout << "Failed to join Thread : " << strerror(err) << std::endl;
}
}
int main()
{
threads T;
T.create_thread();
T.join_thread();
std::cout << "Exiting Main" << std::endl;
return 0;
}
Note:
I have checked all existing questions and answer in Stackoverflow.
But none of them have clear answer.
The above c++ code is a sample code(copied from Internet and updated to show my actual problem)

I have tried this and its working (Posting the answer, to help others)
#include <iostream>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
void *
threadFunc(void * arg)
{
std::cout << "Thread Function :: Start" << std::endl;
// Sleep for 2 seconds
sleep(2);
std::cout << "Thread Function :: End" << std::endl;
return NULL;
}
class threads
{
private:
pthread_t threadId;
int err;
public:
threads():err(0){ threadId = pthread_t(); std::cout <<threadId<<std::endl;};
~threads(){};
void create_thread();
void join_thread();
};
void
threads::create_thread()
{
// Create a thread that will function threadFunc()
err = pthread_create(&threadId, NULL, &threadFunc, NULL);
// Check if thread is created sucessfuly
if (err)
{
std::cout << "Thread creation failed : " << strerror(err);
}
else
{
std::cout << "Thread Created with ID : " << threadId << std::endl;
}
}
void
threads::join_thread()
{
err = pthread_join(threadId, NULL);
// check if joining is sucessful
if (err)
{
std::cout << "Failed to join Thread : " << strerror(err) << std::endl;
}
}
int main()
{
threads T;
T.create_thread();
T.join_thread();
std::cout << "Exiting Main" << std::endl;
return 0;
}

Related

How do I pass member functions to g_source_set_callback?

I am trying to pass member function pointers to g_source_set_callback to queue them. This is a dummy code that I wrote.
#include<glib.h>
#include<iostream>
#include<thread>
#include<chrono>
using namespace std;
using namespace std::chrono_literals;
class executor
{
private:
GMainLoop* main_loop;
GMainContext* worker_context;
thread worker_thread;
void worker_loop()
{
g_main_context_push_thread_default(worker_context);
cout << "Starting main loop" << endl;
g_main_loop_run(main_loop);
cout << "Finished main loop" << endl;
g_main_context_pop_thread_default(worker_context);
}
void queue_callback(int (*callback)(void))
{
GSource* idle_source = g_idle_source_new();
g_source_set_callback(idle_source, (GSourceFunc)callback, NULL, NULL);
g_source_attach(idle_source, worker_context);
g_source_unref(idle_source);
}
int func1()
{
cout << "func1 started" << endl;
this_thread::sleep_for(5s);
cout << "func1 finished waiting" << endl;
return 0;
}
int func2()
{
cout << "func2 started" << endl;
this_thread::sleep_for(1s);
cout << "func2 finished waiting" << endl;
return 0;
}
public:
executor()
{
worker_context = g_main_context_new();
main_loop = g_main_loop_new(worker_context, false);
worker_thread = thread(&executor::worker_loop, this);
}
~executor()
{
cout << "Stopping main loop" << endl;
GSource* idle_source = g_idle_source_new();
g_source_set_callback(idle_source, (GSourceFunc)g_main_loop_quit, main_loop, NULL);
g_source_attach(idle_source, worker_context);
g_source_unref(idle_source);
if (worker_thread.joinable())
{
worker_thread.join();
}
cout << "Removing references to main loop and context" << endl;
g_main_loop_unref(main_loop);
g_main_context_unref(worker_context);
}
void start()
{
queue_callback(func1);
queue_callback(func2);
}
};
int main()
{
executor e;
e.start();
return 0;
}
I know that you cannot pass non-static member function like that, so, I get following compilation error as expected.
test.cpp: In member function ‘void executor::start()’:
test.cpp:79:37: error: invalid use of non-static member function ‘int executor::func1()’
queue_callback(func1);
^
test.cpp:35:13: note: declared here
int func1()
^~~~~
test.cpp:80:37: error: invalid use of non-static member function ‘int executor::func2()’
queue_callback(func2);
^
test.cpp:43:13: note: declared here
int func2()
^~~~~
I saw someone using function objects to wrap the member functions. So, I tried this.
#include<glib.h>
#include<iostream>
#include<thread>
#include<chrono>
#include<functional>
using namespace std;
using namespace std::chrono_literals;
class executor
{
private:
GMainLoop* main_loop;
GMainContext* worker_context;
thread worker_thread;
void worker_loop()
{
g_main_context_push_thread_default(worker_context);
cout << "Starting main loop" << endl;
g_main_loop_run(main_loop);
cout << "Finished main loop" << endl;
g_main_context_pop_thread_default(worker_context);
}
void queue_callback(const function<int()>* callback)
{
GSource* idle_source = g_idle_source_new();
g_source_set_callback(idle_source, reinterpret_cast<GSourceFunc>(&on_callback), const_cast<function<int()>*>(callback), NULL);
g_source_attach(idle_source, worker_context);
g_source_unref(idle_source);
}
static int on_callback(const function<int()>* callback)
{
return (*callback)();
}
int func1()
{
cout << "func1 started" << endl;
this_thread::sleep_for(5s);
cout << "func1 finished waiting" << endl;
return 0;
}
int func2()
{
cout << "func2 started" << endl;
this_thread::sleep_for(1s);
cout << "func2 finished waiting" << endl;
return 0;
}
public:
executor()
{
worker_context = g_main_context_new();
main_loop = g_main_loop_new(worker_context, false);
worker_thread = thread(&executor::worker_loop, this);
}
~executor()
{
cout << "Stopping main loop" << endl;
GSource* idle_source = g_idle_source_new();
g_source_set_callback(idle_source, (GSourceFunc)g_main_loop_quit, main_loop, NULL);
g_source_attach(idle_source, worker_context);
g_source_unref(idle_source);
if (worker_thread.joinable())
{
worker_thread.join();
}
cout << "Removing references to main loop and context" << endl;
g_main_loop_unref(main_loop);
g_main_context_unref(worker_context);
}
void start()
{
cout << "Submitting func1 callback" << endl;
function<int()> callback1 = [this]() {
return func1();
};
queue_callback(&callback1);
cout << "Submitting func2 callback" << endl;
function<int()> callback2 = [this]() {
return func2();
};
queue_callback(&callback2);
}
};
int main()
{
executor e;
e.start();
return 0;
}
This code compiles, but I keep getting either segmentation fault or bad_function_call exception.
Starting main loop
Submitting func1 callback
Submitting func2 callback
Stopping main loop
func1 started
func1 finished waiting
terminate called after throwing an instance of 'std::bad_function_call'
what(): bad_function_call
Aborted (core dumped)
I think I am getting error because callback1 and callback2 are local objects and by the time they are executed, memory for them is freed.
How do I fix this? I thought of using unique_ptrs, but couldn't figure out how as g_source_set_callback takes int (*GSourceFunc) void as second argument and void* as third.
I figured it out.
I create a new std::function object and pass it to g_source_set_callback. When on_callback is called, I typecast the void * to std::function<int()>*, call it and delete it.
Here is the working code.
#include<glib.h>
#include<iostream>
#include<thread>
#include<chrono>
#include<functional>
using namespace std;
using namespace std::chrono_literals;
class executor
{
private:
GMainLoop* main_loop;
GMainContext* worker_context;
thread worker_thread;
void worker_loop()
{
g_main_context_push_thread_default(worker_context);
cout << "Starting main loop" << endl;
g_main_loop_run(main_loop);
cout << "Finished main loop" << endl;
g_main_context_pop_thread_default(worker_context);
}
void queue_callback(function<int()>&& callback)
{
GSource* idle_source = g_idle_source_new();
g_source_set_callback(idle_source, on_callback, new function<int()>(callback), NULL);
g_source_attach(idle_source, worker_context);
g_source_unref(idle_source);
}
static int on_callback(void* ptr)
{
function<int()>* callback = static_cast<function<int()>*>(ptr);
int ret = (*callback)();
delete callback;
return ret;
}
int func1()
{
cout << "func1 started" << endl;
this_thread::sleep_for(5s);
cout << "func1 finished waiting" << endl;
return 0;
}
int func2()
{
cout << "func2 started" << endl;
this_thread::sleep_for(1s);
cout << "func2 finished waiting" << endl;
return 0;
}
public:
executor()
{
worker_context = g_main_context_new();
main_loop = g_main_loop_new(worker_context, false);
worker_thread = thread(&executor::worker_loop, this);
}
~executor()
{
cout << "Stopping main loop" << endl;
GSource* idle_source = g_idle_source_new();
g_source_set_callback(idle_source, (GSourceFunc)g_main_loop_quit, main_loop, NULL);
g_source_attach(idle_source, worker_context);
g_source_unref(idle_source);
if (worker_thread.joinable())
{
worker_thread.join();
}
cout << "Removing references to main loop and context" << endl;
g_main_loop_unref(main_loop);
g_main_context_unref(worker_context);
}
void start()
{
cout << "Submitting func1 callback" << endl;
queue_callback([this]() { return func1(); });
cout << "Submitting func2 callback" << endl;
queue_callback([this]() { return func2(); });
}
};
int main()
{
executor e;
e.start();
return 0;
}

linux c++ use std::thread join, throw exception

my project use three Level process mode. In order to the code after the fork does not inherit from the worker thread of the previous process, so create sub thread to fork sub process when each called.
Now, I found some problems at following describe:
1. the grandson process create a std::thread(work_thread), when called the join() method, it's throw a exception
2. if the son process dose not in sub thread call fork() method, then it's does not thow exception
3. if in grandson process create a empty std::thread(it's nothing to do) before the work thread create, and the empty thread called join() method after the work thread called join() , then it is does not throw the exception. but if the empty thread called join() before work thread, it's also throw the same exception
if you can help me, please write your answer, i will thank you very much
the following code is test case:
#include <iostream>
#include <unistd.h>
#include <wait.h>
#include <thread>
using namespace std;
int main(int argc, char **argv)
{
std::thread t([]() {
int l2pid = fork();
if(l2pid > 0)
waitpid(l2pid, NULL, 0);
else if (l2pid == 0)
{
std::thread t2([]() {
int l3pid = fork();
if (l3pid > 0)
waitpid(l3pid, NULL, 0);
else if (l3pid == 0){
//std::thread empty_thread([](){
//});
std::thread work_thread([](){
for(int i = 0; i < 5; i++){
std::cout << "working..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
if(work_thread.joinable())
work_thread.join();
//if(empty_thread.joinable())
// empty_thread.join();
std::cout << "L3 Process Exit!" << std::endl;
}
});
if (t2.joinable())
t2.join();
std::cout << "L2 Process Exit!" << std::endl;
}
});
if (t.joinable())
t.join();
std::cout << "Main Process Exit!" << std::endl;
return 0;
}
i use pthread_create and pthread_join also return EDEADLK
#include <iostream>
#include <unistd.h>
#include <wait.h>
#include <thread>
#include <vector>
#include <pthread.h>
using namespace std;
void *work_thread(void *)
{
for (int i = 0; i < 5; i++)
{
std::cout << "working..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return NULL;
}
void *t2_function(void *)
{
int l3pid = fork();
if (l3pid > 0)
{
waitpid(l3pid, NULL, 0);
}
else if (l3pid == 0)
{
pthread_t thread_handle;
int ret = pthread_create(&thread_handle, NULL, work_thread, NULL);
std::this_thread::sleep_for(std::chrono::seconds(3));
void *pthread_ret = NULL;
std::cout << "thread_handle:" << thread_handle << ",pthread_self:" << pthread_self() << std::endl;
ret = pthread_join(thread_handle, &pthread_ret);
std::cout << "pthread_join:" << ret << std::endl;
std::cout << "L3 Process Exit!" << std::endl;
}
}
void * t1_function(void *)
{
int l2pid = fork();
if (l2pid > 0)
waitpid(l2pid, NULL, 0);
else if (l2pid == 0)
{
pthread_t l2;
pthread_create(&l2, NULL, t2_function, NULL);
pthread_join(l2, NULL);
std::cout << "L2 Process Exit!" << std::endl;
}
}
int main(int argc, char **argv)
{
pthread_t l1;
pthread_create(&l1, NULL, t1_function, NULL);
pthread_join(l1, NULL);
std::cout << "L1 Process Exit!" << std::endl;
return 0;
}

Boost Interprocess sharing a vector causes strange deadlock (full code sample)

I am sharing a boost::interprocess::vector across two processes, using a boost::interprocess::named_mutex and boost::interprocess::named_condition.
The reader begins first, obtaining the mutex and waiting for data to be written. The writer obtains the mutex, begins writing but it hangs on the line where it updates the shared vector.
If I run the program I get the following output:
Reader trying to get mutex
Reader waiting for data
Writer attempting to get mutex
Writer got mutex. Number of items to write: 2
Writing value: 1
The writer has two items to insert in the vector, but for some reason it stops after inserting the first and just hangs.
This is the code for the writer (full code further below):
void write(const std::vector<T>& items)
{
std::cout << "Writer attempting to get mutex" << std::endl;
scoped_lock<named_mutex> lock(*mutex);
{
std::cout << "Writer got mutex. Number of items to write: " << items.size() << std::endl;
for(const auto& item : items)
{
std::cout << "Writing value: " << item << std::endl;
vec->push_back(item); // <--------------------------- HANGS HERE -----
}
std::cout << "Writer notifying reader" << std::endl;
cond_empty->notify_all();
}
std::cout << "Writer finished" << std::endl;
}
This is the full code (should be able to copy, paste and run):
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
#include <string>
#include <cstdlib> //std::system
#include <iostream>
#include <memory>
using namespace boost::interprocess;
template<typename T>
struct MySharedData
{
using ShmemAllocator = allocator<T, managed_shared_memory::segment_manager>;
using MyVector = vector<T, ShmemAllocator>;
MySharedData(const bool isConsumer, const std::string& sharedMemoryName, const std::string& blockName, const int numBytes) : shared_memory_name(sharedMemoryName), block_name(blockName)
{
is_consumer = isConsumer;
segment.reset(new managed_shared_memory(open_or_create, sharedMemoryName.c_str(), numBytes));
const ShmemAllocator alloc_inst(segment->get_segment_manager());
vec = segment->find_or_construct<MyVector>(blockName.c_str())(alloc_inst);
cond_empty.reset(new named_condition(open_or_create, sharedMemoryName.c_str()));
mutex.reset(new named_mutex(open_or_create, sharedMemoryName.c_str()));
}
~MySharedData()
{
if(is_consumer)
{
segment->destroy<MyVector>(block_name.c_str());
}
}
void write(const std::vector<T>& items)
{
std::cout << "Writer attempting to get mutex" << std::endl;
scoped_lock<named_mutex> lock(*mutex);
{
std::cout << "Writer got mutex. Number of items to write: " << items.size() << std::endl;
for(const auto& item : items)
{
std::cout << "Writing value: " << item << std::endl;
vec->push_back(item); // <--------------------------- HANGS HERE -----
}
std::cout << "Writer notifying reader" << std::endl;
cond_empty->notify_all();
}
std::cout << "Writer finished" << std::endl;
}
std::vector<T> read()
{
std::vector<T> toReturn;
bool continue_trying = true;
while(continue_trying)
{
std::cout << "Reader trying to get mutex" << std::endl;
scoped_lock<named_mutex> lock(*mutex);
{
if(nullptr != vec )
{
if(vec->empty())
{
std::cout << "Reader waiting for data" << std::endl;
cond_empty->wait(lock);
std::cout << "Reader notified of data" << std::endl;
}
for(auto& t : *vec)
{
std::cout << "Reading: " << t << std::endl;
toReturn.push_back(t);
}
continue_trying = false;
}
else
{
std::cout << "No data to read from shared memory: " << shared_memory_name << " block: " << block_name << std::endl;
continue_trying = false;
}
}
}
std::cout << "Reader finished" << std::endl;
return toReturn;
}
std::unique_ptr<named_mutex> mutex{nullptr};
MyVector* vec{nullptr};
std::unique_ptr<managed_shared_memory> segment{nullptr};
std::unique_ptr<named_condition> cond_empty;
bool is_consumer{false};
std::string shared_memory_name;
std::string block_name;
};
void parent()
{
MySharedData<int> msd1(false, "a", "b", 100000);
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
msd1.write(vec);
}
void child()
{
MySharedData<int> msd2(true, "a", "b", 100000);
std::vector<int> x = msd2.read();
}
int main()
{
shared_memory_object::remove("a");
shared_memory_object::remove("b");
shared_memory_object::remove("c");
shared_memory_object::remove("d");
named_mutex::remove("a");
named_mutex::remove("b");
named_mutex::remove("c");
named_mutex::remove("d");
named_condition::remove("a");
named_condition::remove("b");
named_condition::remove("c");
named_condition::remove("d");
// The below code spawns the parent method off to a separate process
pid_t pid = fork();
if(pid == 0)
{
//child();
parent();
}
else if(pid > 0)
{
//parent();
child();
}
std::cout << "FINISHED" << std::endl;
}

swapcontext. What's meaning of field uc_stack in struct ucontext_t?Who use it? The coroutine or the coroutine's signal handler? How can I test it?

What's meaning of field uc_stack in struct ucontext_t?Who use it? The coroutine or the coroutine's signal handler? How can I test it? For example
#include <iostream>
#include <ucontext.h>
#include <queue>
#include <signal.h>
using namespace std;
void sigHandler(int signo)
{
printf("sigHandler:%x\n", &signo);
exit(-1);
}
queue<int> qProduct;
void consumer(ucontext_t* pConsumer, ucontext_t* pProducer)
{
char a[SIGSTKSZ] = {0};
while(1)
{
if(qProduct.size() > 0)
{
cout << __FUNCTION__ << "|" << qProduct.front() << endl;
qProduct.pop();
}
else
{
cout << pConsumer << "|" << pProducer << endl;
swapcontext(pConsumer, pProducer);
}
}
}
void producer(ucontext_t* pConsumer, ucontext_t* pProducer, bool* pFinished)
{
for(int i=0; i<10; i++)
{
if(qProduct.size() < 5)
{
qProduct.push(i);
cout << __FUNCTION__ << "|" << i << endl;
}
else
{
cout << pConsumer << "|P|" << pProducer << endl;
swapcontext(pProducer, pConsumer);
}
}
cout << pConsumer << "|P|" << pProducer << endl;
swapcontext(pProducer, pConsumer);
*pFinished = true;
}
int main(int argc, char* argv[])
{
ucontext_t Main, Consumer, Producer;
/* The stack for the iterator function. */
char consumer_stack[SIGSTKSZ];
char producer_stack[SIGSTKSZ];
cout << "SIGSTKSZ:" << SIGSTKSZ << endl;
/* Flag indicating that the iterator has completed. */
volatile bool bFinished = false;
getcontext(&Consumer);
Consumer.uc_link = &Main;
Consumer.uc_stack.ss_sp = consumer_stack;
Consumer.uc_stack.ss_size = sizeof(consumer_stack);
makecontext(&Consumer, (void (*)(void))consumer, 2, &Consumer, &Producer);
getcontext(&Producer);
Producer.uc_link = &Main;
Producer.uc_stack.ss_sp = producer_stack;
Producer.uc_stack.ss_size = sizeof(producer_stack);
makecontext(&Producer, (void (*)(void))producer, 3, &Consumer, &Producer, &bFinished);
if(!bFinished)
{
swapcontext(&Main, &Producer);
}
return 0;
}
Who use the stack "consumer_stack", "consumer" or "sigHandler"?How to prove it?

Simple timer mechanism with boost - Issue [Re-rum of run mechanism does not respond with handler message]

Am very much new to C++ and boost library
i have constructed a simple timer mechanism
my issue :
On the first timer run call timer.StartAppTimer(1,10); i am getting the handler message
but when i re-run the start timeer again it says started but after 10 seconds i don't receive no handler message..
Please guide
Below is my code:
#include <iostream>
#include <windows.h>
#include <timer.h>
#define sleep(n) Sleep(1000 * n)
using namespace boost::posix_time;
using namespace std;
void handler1(int id,const boost::system::error_code &ec)
{
if (ec == boost::asio::error::operation_aborted)
{
std::cout << microsec_clock::local_time() << " Handler1: Timer 1 was cancelled or retriggered." << std::endl;
std::cout << "TIMER ID : " << id<< std::endl;
}
else
{
std::cout << microsec_clock::local_time() << " Handler1: expired." << std::endl;
std::cout << "fsm RECIEVE msgBuf : " << id<< std::endl;
}
}
Mytimer::Mytimer()
: m_pTimer(NULL),
m_pThread(NULL)
{
m_pTimer = new boost::asio::deadline_timer(io_service1);
}
void Mytimer::runTimerThread()
{
std::cout << "IO Service started " << std::endl;
io_service1.run();
}
void Mytimer::startTimer(int time,int timerId)
{
m_pTimer->expires_from_now(boost::posix_time::seconds(time));
m_pTimer->async_wait(boost::bind(handler1,timerId,boost::asio::placeholders::error));
m_pThread = new boost::thread(&Mytimer::runTimerThread, this);
}
void Mytimer::stopTimer()
{
io_service1.reset();
io_service1.stop();
}
bool Mytimer::isRunning()
{
time_duration td = m_pTimer->expires_from_now();
if (td.total_seconds() > 0)
{
return true;
}
return false;
}
void TimerAccess::StartAppTimer(int Timerid,int TimerPeriod){
std::cout << "TIMER ID : " << Timerid<< std::endl;
if (Timerid == APPTIMER1){
timer1.startTimer(TimerPeriod,Timerid);
}
if (Timerid == APPTIMER2){
timer2.startTimer(TimerPeriod,Timerid);
}
if (Timerid == APPTIMER3){
timer3.startTimer(TimerPeriod,Timerid);
}
}
void TimerAccess::StopTimer(int Timerid){
if (Timerid == APPTIMER1){
timer1.stopTimer();
}
if (Timerid == APPTIMER2){
timer2.stopTimer();
}
if (Timerid == APPTIMER3){
timer3.stopTimer();
}
// return -1;
}
int main()
{
cout << " before timer construction" << endl;
TimerAccess timer;
timer.StartAppTimer(1,10);
sleep(15);
cout << " before starting timer 2" << endl;
timer.StartAppTimer(1,10);
sleep(30);
cout << " END OF MAIN " << endl;
}