An issue with arguments for detached thread - c++

I am working on a school project (simulation of virtual memory), where we are supposed to use detached threads. There are also other limitations to what we can use but I will mention that later. The problem is that when I give the pthread_create function the last argument as (void*)something and the created thread is detached, the function called by pthread_create will recieve the argument, but since the thread is detached, the original arguments are deleted as soon as the function from where I called pthread_create finishes - that means the argument in the called function is no longer valid and therefore I get segmentation faults etc.. Here is a part of the code (cant post it whole, its very big):
bool CProcManager::NewProcess(void* processArg, void(*entryPoint)(CCPU*, void*), bool copyMem) {
uint32_t free_page;
pthread_attr_t attr;
pthread_t thread;
if (proc_cnt >= 63)
return 0;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (!FindFreePage(free_page)) return 0;
free_page = (free_page << 12) | 7;
CProcManager ccpu(m_MemStart, free_page);
ThrArgs args(entryPoint, (void *) processArg, ccpu);
proc_cnt++;
if (pthread_create(&thread, NULL, StartWork, (void *) &args))
return 0;
//pthread_mutex_lock(&start_mtx);
//pthread_cond_wait(&start_cond, &start_mtx);
//pthread_mutex_unlock(&start_mtx);
return 1;
}
Here you can see that this function gets a poitner to void and a pointer to function as parameters. pthread_creates tells the thread to call the "StartWork" function with argument "args", which is a structure containing a pointer to function, a pointer to void and an object of type CProcManager.
void* CProcManager::StartWork(void* arguments) {
//pthread_mutex_lock(&start_mtx);
ThrArgs *args = (ThrArgs*) arguments;
CProcManager ccpu = args->ccpu;
//pthread_cond_signal(&start_cond);
//pthread_mutex_unlock(&start_mtx);
args->entryPoint(&ccpu, args->processArg);
ccpu.RemovePage((ccpu.m_PageTableRoot >> 12) * PAGE_SIZE, false);
pthread_mutex_lock(&end_mtx);
proc_cnt--;
pthread_cond_signal(&end_cond);
pthread_mutex_unlock(&end_mtx);
return (NULL);
}
In this function, I finally call the function I had a pointer to. As you can guess, the arguments become invalid when the "NewProcess" function ends, so I tried to overcome this by adding a condition variable and somehow make a copy of the arguments I have (havent come to a solution yet) and then let the "NewProcess" function end. But there are certain limitations in this project. The function "NewProcess" is being called many times and the threads should run simultaneously (I tried signaling the condition variable after calling entryPoint and that worked), so I cant finish one thread and then do the next. The parameter "void* processArg" of the first function is originally a certain object type and this type cannot be accessed from the two functions above.
So can anyone please give me a suggestion how copy the arguments so I dont have a segmantation fault?

The problem is very simple and is one of object lifetimes and ownership.
You are passing the address of 'args' to the thread, but 'args' is created on the stack and goes out of scope soon after the thread has been started.
do it something like this:
// note: The ThrArgs constructor should take ownership of processArg
std::unique_ptr<ThrArgs> args (new ThrArgs(entryPoint, (void *) processArg, ccpu));
if (pthread_create(&thread, NULL, StartWork, (void *) args.get())) {
args.release();
// ownership of the pointer now belongs to the thread
return 0;
}
then in the thread function:
void* CProcManager::StartWork(void* arguments) {
std::unique_ptr<ThrArgs> args (reinterpret_cast<ThrArgs*>(arguments));
// now use args as a pointer
....
// the arguments will be deleted here
return 0;
}

There are two solutions. The simplest is often just to allocate
the arguments dynamically: in NewProcess:
ThrArgs* args = new ThrArgs( entryPoint, processArg, ccpu );
bool results = pthread_create( &thread, NULL, StartWork, args ) == 0;
if (!results) {
delete args;
}
(You could use std::unique_ptr or std::auto_ptr here as
well. In which case, don't call release on it unless
pthread_create succeeds!)
The alternative is to create a conditional variable over
a boolean, then wait on it before leaving the function, and copy
the parameters and then set the boolean in the new thread: in
NewProcess:
pthread_mutex_lock( &theMutex );
freeToContinue = false;
bool results = pthread_create( &thread, NULL, StartWork, args ) == 0;
if ( results ) {
while ( !freeToContinue ) {
pthread_cond_wait( &theCond, &theMutex );
}
pthread_mutex_unlock( &theMutex );
}
return results;
and in StartWork (the function you pass to pthread_create
must be extern "C", and so cannot be a member):
void* StartWork( void* arguments )
{
pthread_mutex_lock( &theMutex );
ThrArgs args = *static_cast<ThrArgs*>( arguments );
freeToContinue = true;
pthread_cond_broadcast( &theCond );
pthread_mutex_unlock( &theMutex );
// ...
}
(Obviously, I've left out a lot of error checking here.)
Either way: you may have to do something similar with regards to
the processArg argument, since its lifetime is determined by
that of the caller.
And you don't need all of the casts to void*.

Related

Pointer to this* in thread

I have a class and a library (lwip). For some reasons I need to call library's function of thread creation like :
/** The only thread function:
* Creates a new thread
* #param name human-readable name for the thread (used for debugging purposes)
* #param thread thread-function
* #param arg parameter passed to 'thread'
* #param stacksize stack size in bytes for the new thread (may be ignored by ports)
* #param prio priority of the new thread (may be ignored by ports) */
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int
stacksize, int prio);
Inside this function we call pthread:
code = pthread_create(&tmp,NULL,(void *(*)(void *)) function, arg);
My call looks like :
sys_thread_new("main_thread",(lwip_thread_fn)&this->main_thread, NULL,
DEFAULT_THREAD_STACKSIZE,DEFAULT_THREAD_PRIO);
My class method works fine, but I need to change some fielsd of CURRENT class (like 'state'
or else) I have an Idea to pass a pointer to current class to that thread and in thread function change class fields. Some kind of:
sys_thread_new("main_thread",(lwip_thread_fn)&this->main_thread, (void*)this,
DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
Then in main_thread:
void lwip::main_thread(void *arg) {
lwip *p = (lwip*)arg;
p->state = 1;
}
Something like that. But it seems I do something wrong -
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff6e8e700 (LWP 4985)]
0x0000000000403a75 in lwip::main_thread (this=0x7fffffffe4f0, arg=0x80) at
../src/lwip.cpp:50
50 p->state = 1;
There are two problems here: If the main_thread member function is a static member function, you pass a pointer to it using &lwip::main_thread, no casting should be needed. If the function is not static, then you must make it static.
The other problem is that if the instance (this) you pass to the thread function is destructed, the thread function now has a pointer to a destructed object. Be careful with temporary object or passing instances by value.
If the actual thread function can't be static, you can easily solve it with a static wrapper function:
class lwip
{
...
private:
void main_thread() { ... }
static void* main_thread_wrapper(void* arg)
{
reinterpret_cast<lwip*>(arg)->main_thread();
return nullptr;
}
};
...
sys_thread_new("main_thread", &lwip::main_thread_wrapper, this,
DEFAULT_THREAD_STACKSIZE,DEFAULT_THREAD_PRIO);
If you have to cast the pointer to function to get
pthread_create to compile, you have undefined behavior.
If the goal is to call a member function in a different thread,
you need to wrap the call in an extern "C" function. This
means no members and no templates; in the simplest case:
extern "C" void*
startThread( void* p )
{
static_cast<T*>(p)->f();
}
and pass the address of startThread as third argument and
a pointer to the object as fourth. If inheritance is involved,
you must ensure that the fourth argument has the same type as
that in the cast in startThread, e.g.:
pthread_create( &tmp, nullptr, &startThread, static_cast<Base*>( pointerToDerived ) );
if startThread casts to Base*.
If you need arguments to the function as well, you need to pass
a pointer to a struct with both the pointer to the object and
the additional arguments. You also need to ensure that the
lifetime of this struct is sufficient, so that there is no risk
of the thread accessing an already inexistant object. This
often means an additional conditional variable, to ensure that
the thread calling pthread_create doesn't continue before the
new thread has made a copy of all of the relevant data. (Both
Boost threads and the C++11 threads do this for you. It's only
necessary if you need additional data, other than just the
pointer to the object, in the new thread.)
This can get painful if you need to do it for many different
types, and downright impossible if the class in question is
a template. In such cases, one common solution is to use
a Thread object, along the lines of:
class Thread
{
public:
virtual void* run() = 0;
};
and a starter function:
namespace {
extern "C" void*
doStartThread( void* p )
{
return static_cast<Thread*>( p )->run();
}
}
pthread_t
startThread( Thread* thread )
{
pthread_t results;
if ( pthread_create( &results, nullptr, doStartThread, thread ) != 0 ) {
throw std::runtime_error( "Could not create thread" );
}
}
Afterwards, you inherit from Thread, overriding the run
function with whatever you want (and adding any additional data
you might need); the derived class can even be a template.
Again, the lifetime of the Thread object is an issue; the
solution I've usually used has been to require it to be
dynamically allocated, and then delete it at the end of
doStartThread. It's a very good idea to catch it in an
std::unique_ptr in doStartThread, although you still want to
catch exceptions in this function, since otherwise they will
kill the process. And don't forget the delete if
pthread_create fails (since the caller has passed over
ownership. If you really want to be sure:
namespace {
extern "C" void*
doStartThread( void* p )
{
std::unique_ptr<Thread*> object( static_cast<Thread*>( p ) );
try {
return object->run();
} catch ( ... ) {
return somethingElseToReportTheError;
}
}
}
pthread_t
startThread( std::unique_ptr<Thread> thread )
{
pthread_t results;
if ( pthread_create( &results, nullptr, doStartThread, thread.get() ) != 0 ) {
throw std::runtime_error( "Could not create thread" );
}
thread.release(); // AFTER the call has succeeded!
}
I've used this technique successfully in a number of
applications (using std::auto_ptr, since there was no
std::unique_ptr then); typically, the fact that you need to
use dynamic allocation is not an issue, and it solves the
lifetime issue quite nicely. (The alternative would be to use
a conditional variable, blocking the original thread until the
new thread had copied everything over.)
Note that by using a unique_ptr in the interface, you
effectively block the calling thread from further access to the
thread object, by robbing it of its pointer to the object. This
offers an additional guarantee with regards to thread safety.
But of course, this additional guarantee (and the solution to
the lifetime issues) only applies to the Thread object itself,
and not to anything it might point to.

c++ pthread not working

I have a classA which creates a thread and I want the thread running until a variable is set to false.
I create the thread like:
ClassA::ClassA():
m_bContinue(true),
{
pthread_mutex_init(&m_mutex, NULL);
pthread_create(&m_thWorkThread, NULL, &ClassA::ThreadProc, this);
}
I want thread running as long as pClassA->Continue() returns true.
void* ClassA::ThreadProc(void *p) //ThreadProc defined as static member function
{
ClassA *pClassA = reinterpret_cast<ClassA*>(p);
if(pClassA != NULL)
{
while(pClassA->Continue())
{
printf("in the while \n ");
}
}
else
printf("pClassA null \n");
}
Continue is returning m_bcontinue which set to true in the constructor.
bool ClassA::Continue()
{
return bContinue;
}
When I run it, it only enters while loop once and prints "in the while" and program stops. When I do strace, I saw the message +++ killed by SIGSEGV +++.
And when I change the while loop like:
while(1){}
it is working properly. What am I missing?
You cannot launch member functions using pthread_create. Instead, use normal function, pass this to it and call the needed function:
void *ThreadProc (void *p)
{
reinterpret_cast<ClassA*>(p)->ThreadProc (p);
return 0;
}
...
pthread_create(&m_thWorkThread, NULL, &ThreadProc, this);
Or, instead you can use c++11 and its std::thread that allows launching class member functions.
Could the object of type A have a shorter lifetime than the thread ? It seems object A dies too soon. Using while(1), you are no longer referencing A.
Quick question. Where is pthread_join here. I hope you havent missed it. Just curious.

passing one function to different threads

I have to create an application where I'll have to make multiple threads. SoI thought to try making one function and passing it to different threads. Initially I've created two threads and have declared one function to be passed to both of them. All I am trying to do is to pass different integers to those threads and display it in the thread function,here is my code:
DWORD WINAPI Name(LPVOID lpParam)
{
int *Ptr=(int*)lpParam;
for(int j=0;j<2;j++)
{
cout<<"Thread"<<endl;
cout<<*Ptr<<endl;
}
return 0;
}
int main()
{
int a=10,b=15,c=25;
HANDLE thread1,thread2;
DWORD threadID,threadID2;
thread2= CreateThread(NULL,0,Name,LPVOID(a),0,&threadID2);
thread1= CreateThread(NULL,0,Name,LPVOID(b),0,&threadID);
for(int i=0;i<5;i++)
{
cout<<"Main Thread"<<endl;
}
if(thread1==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
exit(0);
}
if(thread2==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
exit(0);
}
return 0;
}
but this code is not running properly,i.e compliles fine,starts fine but afterwards gives a debugging error.
Could someone let let me know of my mistake and how I could correct it coz being able to utilize one function for multiple threads will be really helpful for me.
Wait for your child threads to return. Do this:
int main()
{
int a=10,b=15,c=25;
HANDLE thread[2];
DWORD threadID,threadID2;
thread[1]= CreateThread(NULL,0,Name,LPVOID(a),0,&threadID2);
thread[0]= CreateThread(NULL,0,Name,LPVOID(b),0,&threadID);
for(int i=0;i<5;i++)
{
cout<<"Main Thread"<<endl;
}
if(thread[0]==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
exit(0);
}
if(thread[1]==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
CloseHandle(thread[0]);
exit(0);
}
WaitForMultipleObjects(2, thread, TRUE, INFINITE);
CloseHandle(thread[0]);
CloseHandle(thread[1]);
return 0;
}
The handle of a thread is signaled when the thread is terminated (refer CreateThread).
You are passing the address of a local variable in the function into your thread. By the time the thread gets around to running your function has probably exited main already. So the thread will try to access a variable that no longer exists on the stack so will be reading some random value which when you try to dereference it as a pointer will likely crash.
You main needs to wait. For a simple test just put in a Sleep(10000) or something before it exits. Obviously that's no use for a real program.
To summarize the comments: There are two ways you can pass data. Either directly inside the void pointer, because "void pointer" is an integral type and thus can represent integers (but it doesn't necessarily have the same width as int), or indirectly by passing an actual address of the thing you care about.
Method 1 (pass the value):
DWORD WINAPI Name(LPVOID lpParam)
{
intptr_t n = reinterpret_cast<intptr_t>(lpParam);
// ...
}
int main()
{
intptr_t a = 10;
thread1 = CreateThread(NULL, 0, Name, reinterpret_cast<void *>(a), 0, &threadID);
// ... ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
For this method, we use the integral type intptr_t, which has the same width as void *. We use reinterpret-casts to store and retrieve arbitrary integral values.
Method 2 (pass a pointer):
DWORD WINAPI Name(LPVOID lpParam)
{
T * p = static_cast<T *>(lpParam);
// ... use *p ...
}
int main()
{
T thing_I_care_about;
thread1 = CreateThread(NULL, 0, Name, &thing_I_care_about, 0, &threadID);
// ... ^^^^^^^^^^^^^^^^^^^
}
This is the more general method, but requires that thing_I_care_about remain alive, and it becomes a brittle shared state, so lifetime management and synchronisation become issues. Note that any object pointer is implicitly convertible to void *, so there's no need for the cast at the call site.
Finally, as others have commented, don't forget to join or detach your threads.

Close a thread when done with it

How do you close a thread, when you done? like making sure nothing is open anymore or runing?
so far i know how to open it, but .. not how to close it right
int iret1;
pthread_t thread1;
char *message1;
void *multithreading1( void *ptr ) {
while (1) {
// Our function here
}
}
int main (int argc, char * const argv[]) {
if( (iret1=pthread_create( &thread1, NULL, multithreading1, (void*) message1)) )
{
printf("Thread creation failed: %d\n", iret1);
}
return 0;
}
"How do you close a thread, when you done?"
Either by just simple returning from that function or calling pthread_exit function.
Note that calling return also causes the stack to be unwound and variables declared within start routine to be destroyed, thus it's more preferable than pthread_exit function:
An implicit call to pthread_exit() is made when a thread other than the thread in
which main() was first invoked returns from the start routine that was used to
create it. The function's return value shall serve as the thread's exit status.
For more information also have a look at: return() versus pthread_exit() in pthread start functions
"making sure nothing is open anymore or runing"
Instead of making sure whether your thread is still running, you should wait for its termination by using pthread_join function.
Here's an example:
void *routine(void *ptr) {
int* arg = (int*) ptr; // in C, explicit type cast is redundant
printf("changing %d to 7\n", *arg);
*arg = 7;
return ptr;
}
int main(int argc, char * const argv[]) {
pthread_t thread1;
int arg = 3;
pthread_create(&thread1, NULL, routine, (void*) &arg);
int* retval;
pthread_join(thread1, (void**) &retval);
printf("thread1 returned %d\n", *retval);
return 0;
}
output
changing 3 to 7
thread1 returned 7
To do this, you either return from the thread function (multithreading1) or call pthread_exit().
For more information, see POSIX Threads Programming.

pthread_create segmentation fault

I'm using the method 'pthread_create' in my program, and get a segmentation fault INSIDE THIS METHOD.
What can possibly cause this? I'm calling this function with the correct arguments' types!
this is the code:
pthread_t* _daemon;
void* writer(void* arg){
// stuff that dont involve "arg"...
}
int initdevice(){
if(pthread_create(_daemon, NULL, &writer, NULL) != 0) //seg in this line
{
cerr << "system error\n";
return ERR_CODE;
}
return SUCCESS;
}
int main () {
initdevice();
return 0;
}
Note: I've tried to run it also without the '&' before the calling to writer in pthread_create, and also - we've tried sending to this method some void* argument instead of the last NULL argument.
Your probelem is here:
pthread_t* _daemon;
This should be:
pthread_t daemon;
Then change the call to pthread_create:
if(pthread_create(&daemon, NULL, &writer, NULL) != 0)
The idea is that pthread_create takes a pointer to an existing pthread_t object so that it can fill in the details. You can think of it as the C version of a constructor. Initially the pthread_t object is uninitialized this initializes it.
In addition your code is still probably not going to always work as you do not wait for the thread to finish. Make sure your main thread does not finish before all the children:
int main ()
{
initdevice();
pthread_join(daemon, NULL); // wait for the thread to exit first.
return 0;
}
you must allocate _daemon variable with new or malloc function, because you have use of a pointer. like bellow :
pthread_t* _daemon;
_daemon = new pthread_t;