I have a class member functionA which creates a thread to run another functionB. FunctionB would perform some operation and stop after some time ( it is kind of fire and forget function call and the number of functionA calls and threads needed would depends on the run time result). FunctionA would be called multiple times. I realized that the pthread_create would take in pthread_t for the first parameter, and the pthread_t must be available while creating the thread. So, I could not declare it as local like below. So where could I declare the pthread_t?
void classA::functionA(int param)
{
pthread_t t; //could not declare local because functionA might return and destroy t before thread being created.
pthread_create(&t , NULL, functionB, param);
}
void functionB(int param)
{
}
Firstly, you can put your pthread_t on the stack: your functionA is fine in that respect. pthread_create stores the thread handle directly, so as soon as it returns the handle is valid. The newly created thread hasn't necessarily started executing yet, but that doesn't matter, as it won't touch that handle.
However, you need to manage your thread somehow. If you don't explicitly create it detached, then you must call pthread_join or pthread_detach on your handle. If you don't call either then you are leaking resources. If this really is a "fire and forget" thread then you should use pthread_detach to ensure that the OS cleans up when the thread finishes.
Either way, you need to ensure that the objects accessed by the thread outlive any potential accesses to them by the thread (e.g. by not destroying them until an "I don't need these objects any more" flag is set)
You can have a pthread_t variable on the stack, there is no problem with that.
Is there a reason you don't use a thread wrapper like boost::thread? It would make your life much easier. http://www.boost.org/doc/libs/1_45_0/doc/html/thread/thread_management.html
Another thing is that you can't just fire and forget a thread because once you do the object must not be destroyed before the other thread stops accessing it. In other words, the destructor of your object must make sure there are no other threads accessing the object.
I don't believe you have a problem as pthread_create() won't return before the new thread identifier has been written into t so there is no need to do new pthread_t at all. You need to check the return from pthread_create() of course though.
I would do it this way:
class classA
{
void functionA();
static void void functionB(classA* aThis);
};
void classA::functionA(int param)
{
//create thread: note that this way pthread_t can even become the class-member
}
void classA::functionB(classA* aThis)
{
classA* theThis = static_cast<classA*>(aThis);
//now you can access classA members here easily
}
Related
I have a function that will be called multiple times and this function will create a new pthread every it gets called. And i need to pass some arguments using struct to the pthread every it gets created.
Does it require to have a mutex locking for those struct (in the function that create the pthread) whenever passing the arguments to the pthread?
Please advise.
i need to pass some arguments using struct to the pthread every it gets created.
I suppose you must mean something along these lines:
struct args {
int arg1;
double arg2;
char *arg3;
};
void *thread_func(void *p) {
struct args *args = p;
// ... do something with args ...
return some_value;
}
// ...
void foo() {
pthread_t tid;
struct args *args;
// ...
args = some_expression;
pthread_create(&tid, NULL, thread_func, args);
// ...
}
Does it require to have a mutex locking for those struct (in the
function that create the pthread) whenever passing the arguments to
the pthread?
Using a mutex in function foo() alone would do no good for anyone. Mutexes provide for synchronization only between two different pieces of code that both successfully lock the same one (necessarily at different times).
More generally, launching a new thread synchronizes all actions in the new thread with all actions preceding the thread launch in the parent thread. In particular, the new thread can read the contents of the argument structure without any special measures and without thereby causing a data race, provided that no other thread modifies that structure, and the structure's lifetime does not expire. The new thread can even modify the argument structure without a data race, provided that no other thread accesses it at all, and its lifetime does not expire.
There are definitely still ways you could get into trouble, however, as the above provisos suggest. Appropriate bi- or multi-lateral use of mutexes would resolve some such issues, but not others. For example, if the args structure presented to the new thread is in fact an automatic variable of the function that launches the thread, and the thread in fact accesses the structure via the provided pointer, then there is a potential data race between the new thread's access(es) to the structure and the end of its lifetime. For example,
void foo() {
pthread_t tid;
struct args args; // an automatic variable
// ...
pthread_create(&tid, NULL, thread_func, &args);
// ...
// the lifetime of args ends when control reaches here
}
In such a case, you need to ensure that the new thread performs all its accesses to the args structure before foo() (running in a different thread) returns. A mutex (alone) cannot do that for you -- instead, you want a condition variable (which must be used together with a mutex), or a semaphore, or one of a variety of other alternatives.
This is mainly a question about scope and threads. Let's say we have the following struct.
struct Test
{
int number;
std::string name;
};
An instance of this struct will be used as an argument in the pthread_create function. Here is an example of what this might look like.
pthread_t tid[5];
for(int i = 0; i < 5; ++i)
{
Test test;
test.number = 5;
test.name = "test";
pthread_create(&tid[i], NULL, func, (void *)&test);
}
Is this acceptable? Since test is declared in the for's scope, that means we can only rely on it existing during a single iteration of the for loop.
When pthread_create is called, a pointer to test is given as an argument. This means that func is receiving the same pointer that is passed in to pthread_create. This means that when test goes out of scope, we can no longer rely on that pointer referring to test. If we were to create more locals, hence changing the stack, the location that the pointer points to would be overwritten by those new locals. Is this correct?
Is this acceptable?
In general, no, for the reasons you stated. Specifically, the thread's entry-function may not start executing until after the Test object has been destroyed, or the Test object might be destroyed while the thread's entry-function is still using it. Either of those possibilities will lead to undefined behavior (and a program that only works correctly "sometimes").
You need to guarantee that the data you pass to the thread remains valid for as long as the thread needs to use it. One way to do that is to allocate that Test object on the heap, and have the thread call delete on the Test-pointer when it's done using it. Alternatively, you could use a condition variable to "pause" the main thread until the child pthread signals that it is done accessing the Test on the main thread's stack, so that it is now safe for the main thread to continue execution.
If we were to create more locals, hence changing the stack, the
location that the pointer points to would be overwritten by those new
locals. Is this correct?
Yes, you understand the issue correctly.
I want to know what would happen when destructor gets called on an object when the object is stuck in an infinite while loop in a different thread.
// Main thread creates the object
MyClass _obj = new MyClass():
// doing some stuff
delete _obj;
Where,
MyClass::MyClass()
{
// Start a thread which calls MyClass::MyPollingFn()
}
MyClass:: MyPollingFn()
{
// runs in new child thread
while(true)
{
// doing some work
// sleep(5 seconds)
}
}
Explanation:
There is a class object of MyClass which creates a thread and runs MyPollingFn method in an infinite loop. Every iteration of this method can change some class variables. Is it ok to destroy the object from parent thread which holds the object? Is there any possibility of this giving an issue?
If MyPollingFn ever touches this, explicitly or implicitly (e.g. by accessing non-static member variables), then this code would exhibit undefined behavior, as this would become a dangling pointer.
And if it doesn't touch this, then why make it a non-static member function?
There are several possible issues, including
1. Either you will try to join the thread in your destructor, in which case it will block.
Edit
i.e. if you add
MyClass::~MyClass()
{
myThread.join();
}
and leave the MyPollingFunction as it is, it will never finish, so the join will block.
End Edit
Though this code doesn't have a destructor, but perhaps it should.
2. Or the thread will try to "change some class variables" after the class has gone away.
Which is obviously bad.
It might be better to change the
while(true)
to
while(!finished)
where the finished is some kind of thread-safe flag (an e.g. atomic) and set it in the (currently non-existent) destructor.
If you have shared variables between a std::thread and the main thread (or any other thread for that matter), can you still access those shared variables even if you execute the thread::detach() method immediately after creating the thread?
Yes! Global, captured and passed-in variables are still accessible after calling detach().
However, if you are calling detach, it is likely that you want to return from the function that created the thread, allowing the thread object to go out of scope. If that is the case, you will have to take care that none of the locals of that function were passed to the thread either by reference or through a pointer.
You can think of detach() as a declaration that the thread does not need anything local to the creating thread.
In the following example, a thread keeps accessing an int on the stack of the starting thread after it has gone out of scope. This is undefined behaviour!
void start_thread()
{
int someInt = 5;
std::thread t([&]() {
while (true)
{
// Will print someInt (5) repeatedly until we return. Then,
// undefined behavior!
std::cout << someInt << std::endl;
}
});
t.detach();
}
Here are some possible ways to keep the rug from being swept out from under your thread:
Declare the int somewhere that will not go out of scope during the lifetime of any threads that need it (perhaps a global).
Declare shared data as a std::shared_ptr and pass that by value into the thread.
Pass by value (performing a copy) into the thread.
Pass by rvalue reference (performing a move) into the thread.
Yes. Detaching a thread just means that it cleans up after itself when it is finished and you no longer need to, nor are you allowed to, join it.
In the constructor of one of my classes I call the Windows function CreateThread as last operation. The thread is created to execute immediately and I pass the this pointer of my class as lpParameter.
In the thread procedure I cast the parameter passed back to a pointer of my class and name it pThis.
I can see that pThis points to the same memory location as the this pointer I passed when I called CreateThread. However if I look at the member variables accessed by pThis->... they all have wrong values.
I expected the value of this->member_variable used in the class to which the this pointer belongs to be the same as the one I get when writing pThis->member_variable in the thread's procedure.
If I call CreateThread in another member function (not the constructor) everything behaves correctly.
Hence the question: Is it forbidden to call the Windows function CreateThread from within the constructor of a C++ class? If yes, what is the problem?
Clarification:
1) I can confirm that the object always exists. The object gets out of scope only when the entire program ends. As I already said: calling CreateThread from some other member function does work.
2) Corrected the 'wired' typo, should have been 'weird', sorry.
Some code:
I try to post code snippets reducing things to the bare minimum while maintaining the 'faulty' parts.
class CTimerW32 : public CTimer
{
public:
CTimerW32();
~CTimerW32();
private:
static void CALLBACK TimerCallback(LPVOID lpParam, BOOLEAN bReason);
static DWORD WINAPI WaitCompletition(LPVOID lpParam);
private:
HANDLE m_hCompletitionEvent;
HANDLE m_hCompletitionThread;
bool m_bStartDeferred;
};
You can safely ignore the baseclass CTimer as it is just an abstract baseclass enabling build on different platforms.
CTimerW32::CTimerW32()
{
m_bStartDeferred= false;
m_hCompletitionEvent= CreateEvent(NULL, FALSE, FALSE, NULL);
m_hCompletitionThread= CreateThread(NULL, 0, WaitCompletition, this, 0, NULL);
}
Here I can see that m_hCompletitionEvent is valid after the call to CreateEvent.
DWORD WINAPI CTimerW32::WaitCompletition(LPVOID lpParam)
{
CTimerW32* pThis;
DWORD dwRet;
pThis= (CTimerW32*)(lpParam);
while (true) {
// just wait for the completition event to be signaled
dwRet= WaitForSingleObject(pThis->m_hCompletitionEvent, INFINITE);
// ...
if (pThis->m_bStartDeferred) {
// ...
}
}
Here things are going wrong in the call to WaitForSingleObject. As already stated the this pointer of the object of class CTimerW32 (now pThis) still has the same value as the this pointer during thread creation. However the handle in pThis->m_hCompletitionEvent seems to be random data. It is not the value observed after the call to CreateEvent in the constructor.
Creating a thread in a constructor should not be an issue. Also, your object should be fully initialized by the initializer list before any code in the constructor is run to create the thread, so initialization probably isn't an issue.
It is likely that the object you're watching is out of scope and its destructor is called prior to you observing it in the new thread. Try creating the object dynamically with new and see if this still happens, I bet it doesn't as the object won't get destroyed when it falls out of scope.
Obviously, you should keep a pointer to this object in a higher scope so you can eventually delete it too :)
You will probably have the best luck debugging this problem with the aid of Application Verifier. If you turn on the "Basics" option for your program, it will enable PageHeap, which will fault immediately when memory gets freed. If you're stack-allocating the timer variable, you're in less luck, but it should be possible to see in the debugger if at the time you notice the corruption, the thread which created the timer is still within the function where the CTimerW32 function was declared.
Lastly, for this usecase, the Threadpool Timer APIs may work more easily, and with less resource consumption, than creating your own dedicated thread.