Make current/this thread detach.

Hi.

I have a thread that is calling a operator()-function, which is wrapped inside it's own class, to ensure that it always is detaches when it's decstructor is called. But how do I detach the "current" or "this" thread that is calling the function?

I want to do something similar to this:
 
std::this_thread.detach();


But that syntax/way of doing it does not work and is not even an option.
As I understand the description of detach(), that detaches the object you are calling the method of from the current thread, so what you are trying to do would be equivalent to detach()ing this_thread from this_thread (itself), which doesn't make conceptual sense to me.

Could you give a bit more detail on what you're doing or why?
Call from main thread:
1
2
std::thread tAlarm0((FctorGiveAlarm()),this,std::move(strLocalTime),0);
tAlarm0.detach();


Fctor wrapper class (with the destructor that I was talking about):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class FctorGiveAlarm final
{
private:
public:
	FctorGiveAlarm();
	
	~FctorGiveAlarm();

	void operator()(const ZerpAlarmClass* cpZerpAlarm,const std::string& strLocalTime,const u8& strMsgIndex);
};

// Want to detach current thread from the main thread!
FctorGiveAlarm::~FctorGiveAlarm()
{
	std::this_thread-
}

void FctorGiveAlarm::operator()(const ZerpAlarmClass* cpZerpAlarm,const std::string& strLocalTime,const u8& strMsgIndex)
{
	cpZerpAlarm->giveAlarm(strLocalTime,strMsgIndex);
}


1: I create new thread "tAlarm0" to make it call the operator()-function inside the FctorGiveAlarm object that is created.
2: I detach the thread from main thread to let it run independently/ in parallell.
3: My problem - I want the destructor to be able to detach "tAlarm0" when an exception occurs in the main thread or when "tAlarm0" goes out of scope. The reason is that this will guarantee/ensure that the "tAlarm0" will always be detached. But I do not know how to access "tAlarm0" to call it's detach()-function from FctorGiveAlarm's destructor. I want "tAlarm0" to be detached from main thread inside that destructor.
Last edited on
If you detach it immediately after creation, you've done all that's necessary. If an exception occurs during the construction of the thread, the thread is... not constructed (so there is nothing to detach.)
Last edited on
Well, I agree that I do not need this in this code/project. But I still want to learn how to do it! Because maybe I will need it next time I use threads.

Could anyone please explain how to do it in the destructor like I asked above?

I could pass a thread pointer tp which points at the current thread. Then I could do: tp->detach() inside the destructor. But this is probably a bad solution.
Last edited on
Something like this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <chrono>
#include <thread>
#include <iostream>

struct timer_alarm // non-copyable, moveable
{
    timer_alarm( int secs ) : thread( &alarm_fn, secs ) {}

    ~timer_alarm()
    {
        std::cout << "timer_alarm::destructor\n" ;

        if( thread.joinable() )
        {
            std::cout << "detaching the thread\n" ;
            thread.detach() ;
        }
    }

    static void alarm_fn( int secs )
    {
        std::this_thread::sleep_for( std::chrono::seconds(secs) ) ;
        std::cout << "alarm\n" ;
    }

    std::thread thread ;
};

int main()
{
    { timer_alarm(2) ; }

    std::this_thread::sleep_for( std::chrono::seconds(3) ) ;
}
It looks really interesting :). I will take a closer look when I start working at the project again and I'll see if this solves it.

Thanks.
JLBorges, why do you use struct instead of class? Is it just a sense of what different programmers like or is there a difference? I watched a video that said that there are almost no differences between structs and classes.
> JLBorges, why do you use struct instead of class?
> Is it just a sense of what different programmers like or is there a difference?

When the keyword struct or class is used to declare or define a user-defined type, there is only one difference: the default access specifier for members and base classes is public with struct and private with class.

If the coding convention specifies that public members of a class must be declared at the beginning, I use the keyword struct; if it specifies that private members must be declared first, I use the keyword class. What you use depends your personal preference, and that of the other programmers who work on the same program.

It is a non-difference similar to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int* pointer = nullptr ; 
/* or */ 
int *pointer = nullptr ;

if( condition ) {
    // ...
}

/* or */

if( condition ) 
{
    // ...
}


Just be consistent in whatever you choose. Once you start reading real-life code, once you are past the amateur stage, you would have to read, write and maintain code written using different styles - K&R, Allman, and so on. Very soon, you would realize that code written in a consistent style is both readable and understandable; it doesn't really matter what the style is as long as it is consistent.

If you modify or extend a program that you didn't write, preserve the style that is already there - the program's overall consistency of style is more important than your own predilections. Ideally, don't waste time over arguments about struct vs. class, int* p vs int *p, which brace and indentation style to use etc.
Thanks for explaining JLBorges.

However, I am still stuck with the problem that I asked about before in this thread.

I tried to do the same thing as you like this:
1
2
3
FctorGiveAlarm::FctorGiveAlarm(const std::string& strLocalTime, const u8& u8MsgIndex) : m_cAlarmThread(std::thread(&giveAlarm, std::move(strLocalTime), u8MsgIndex))
{
}


But then I get this error:
 
1>c:\users\zerpent\documents\visual studio 2013\projects\zerpalarm\zerpalarm\fctorgivealarm.cpp(9): error C2276: '&' : illegal operation on bound member function expression


Apparently I am not allowed to get the address of funtion giveAlarm when passing it to the thread that is created. How do I solve this?

I even tried to get the address with this syntax as well:
 
&FctorGiveAlarm::giveAlarm


But that did not work either. Omg.
Last edited on
Make FctorGiveAlarm::giveAlarm() a static member function.

If it is non-static, it requires an object of type FctorGiveAlarm (it has a this pointer). You can't continue to execute it concurrently (after detaching the thread) once the object pointed to by the this pointer is destroyed.

And don't do this:
1
2
FctorGiveAlarm::FctorGiveAlarm( const std::string& strLocalTime ... ) :
      m_cAlarmThread( .... std::move(strLocalTime) ) 

There is no certainty that it is safe to treat strLocalTime as an rvalue.

Instead, just pass it by value (and let the compiler optimize away the copy if appropriate):
1
2
FctorGiveAlarm::FctorGiveAlarm( const std::string& strLocalTime ... ) :
      m_cAlarmThread( .... strLocalTime ... ) 
I will try that when I get back to it and hope that it works. I will then tell you if it worked or not.

Thanks for all help and for explaining so well :).
Topic archived. No new replies allowed.