I have a variable in file tracker.hpp:
namespace TRIALS
{
static thread_local int a = -1;
}
I have another class in file called EMP in ema.hpp/ema.cpp
namespace Algo
{
class EMP
{
public:
void Sample();
};
}
namespace Algo
{
void EMP::Sample()
{
std::cout << "model " << std::this_thread::get_id() << " " << &TRIALS::a << " " << TRIALS::a << std::endl;
}
}
Then my main file I have
auto model = Algo::EMP();
void Simulate(const int a)
{
TRIALS::a = a;
model.Sample()
std::cout << "worker " << std::this_thread::get_id() << " " << &TRIALS::a << " " << TRIALS::a << std::endl;
}
int main()
{
std::cout << &TRIALS::a << std::endl;
const int nthreads = 1;
std::cout << "main " << std::this_thread::get_id() << " " << &TRIALS::a << " " << TRIALS::a << std::endl;
std::vector<std::thread> threads;
for(int i=0; i<nthreads; ++i)
{
threads.emplace_back(&Simulate, i);
}
for(auto &thread : threads)
{
thread.join();
}
std::cout << "main " << std::this_thread::get_id() << " " << &TRIALS::a << " " << TRIALS::a << std::endl;
return 0;
}
I am just running one thread for debugging but this is the output:
0x7f9540b621d8
main 140279012532800 0x7f9540b621d8 -1 (As expected)
model 140278985606912 0x7f953f1b469c -1 (Shouldn't this be 0??)
worker 140278985606912 0x7f953f1b4698 0 (As expected)
main 140279012532800 0x7f9540b621d8 -1 (As expected)
I was under the impression that each thread has it's own local copy of TRIALS::a. The a in model correctly gets incremented but when it returns from the function in the same thread, the value is still 0. I am printing out the thread ids and the address of a for good measure and I am seeing that there are actually 3 different versions of TRIALS::a despite only two total threads.
As a bonus question, what is the difference between static thread_local int a and thread_local int a ?
In your example static makes that thread_local object use internal linkage, so that each translation unit (.cpp file) has its own copy of the variable.
See storage class specifiers for details:
The thread_local keyword is only allowed for objects declared at namespace scope, objects declared at block scope, and static data members. It indicates that the object has thread storage duration. It can be combined with static or extern to specify internal or external linkage (except for static data members which always have external linkage), respectively, but that additional static doesn't affect the storage duration.
I.e. you may like to drop that static keyword, so that you only have one copy of the object in the entire application. In the header file do:
namespace TRIALS {
extern thread_local int a;
}
And in one of the .cpp:
thread_local int TRIALS::a = -1;
In C++17, you can make the variable inline to avoid having to provide its definition in a .cpp:
namespace TRIALS {
inline thread_local int a = -1;
}
Related
I am trying to write my own c++ wrapper class for linux using pthreads. The class 'Thread' is supposed to get a generic lambda to run in a different thread and abstract away the required pthread calls for that.
This works fine if the lambdas don't capture anything, however as soon as they capture some shared variables the behaviour seems to become undefined depending on whether or not the template types of two threads are the same or not. If both Thread objects caputre the same types (int and int*) it seems to (probably accidentally) work correctly, however as soon as i pass (e.g. like in my example) an integer A 'aka. stackInt' and an int ptr B 'aka. heapInt' to Thread 1 and only the int ptr B to Thread 2 i get a segfault in Thread 2 while accessing int ptr B.
I know that it must have something to do with the fact that each thread gets its own copy of the stack segment however i cant wrap my head around how that interferes with colsures capturing variables by refernce and calling them. Shouldn't the int ptr B's value point to the same address in each copy of it on the stack? How does the adress get messed up? I really can't wrap my head around whats the exact issue here..
Can anyone help me out here? Thank you in advance.
Here is the full example code:
class 'Thread'
// thread.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
// ******************************* //
// THREAD CLASS //
// ******************************* //
template <typename C>
class Thread
{
private:
C &m_closure;
pthread_t m_thread;
public:
Thread<C>(C &&closure)
: m_closure(closure),
m_thread()
{}
void start()
{
pthread_create(&m_thread, NULL, &Thread::threadFunction, (void *)this);
}
void join()
{
pthread_join(m_thread, NULL);
}
private:
void callbackOnInstance()
{
m_closure();
}
static void * threadFunction(void *);
};
template <typename C>
void * Thread<C>::threadFunction(void *caller)
{
Thread<C> *callerObject = (Thread<C> *)caller;
callerObject->callbackOnInstance();
return nullptr;
}
main() / testing
// main.cpp
// ******************************* //
// TESTING //
// ******************************* //
#define SLEEP_SEC(_sec) usleep((long)(1000 * 1000 * (_sec)))
#include "thread.h"
#include <iostream>
#include <string>
int main(int argc, char **argv)
{
int stackInt = 0;
int *heapInt = new int(0);
// every second each thread increments them, 0.5 s apart from each other
Thread thread1([&]()
{
while(true)
{
SLEEP_SEC(1);
std::cout << "thread #1:" << std::endl;
stackInt += 1;
std::cout << "stack int: " << stackInt << " [" << &stackInt << "]" << std::endl;
*heapInt += 1;
std::cout << "heap int: " << *heapInt << " [" << heapInt << "]" << std::endl;
}
});
thread1.start();
Thread thread2([&]()
{
SLEEP_SEC(0.5);
while(true)
{
SLEEP_SEC(1);
std::cout << "thread #2:" << std::endl;
// if stackInt doesn't get referenced ...
//stackInt += 1;
//std::cout << "stack int: " << stackInt << " [" << &stackInt << "]" << std::endl;
// ... i get a segfault here
*heapInt += 1;
std::cout << "heap int: " << *heapInt << " [" << heapInt << "]" << std::endl;
}
});
thread2.start();
thread1.join();
thread2.join();
}
You've got undefined behaviour, since the lambda objects are actually destroyed immediately after the constructor of Thread completes. To see this, instead of a lambda you could pass an object that prints a message in the destructor:
struct ThreadFunctor
{
int& stackInt;
int* heapInt;
ThreadFunctor(int& si, int* hi)
: stackInt(si),
heapInt(hi)
{
std::cout << "ThreadFunctor created: " << this << '\n';
}
~ThreadFunctor()
{
std::cout << "ThreadFunctor destroyed: " << this << '\n';
}
void operator()() const
{
using namespace std::chrono_literals;
while (true)
{
std::this_thread::sleep_for(1s);
std::cout << "thread #1:" << std::endl;
stackInt += 1;
std::cout << "stack int: " << stackInt << " [" << &stackInt << "]" << std::endl;
*heapInt += 1;
std::cout << "heap int: " << *heapInt << " [" << heapInt << "]" << std::endl;
}
}
};
Thread thread1(ThreadFunctor{stackInt, heapInt});
std::cout << "before start\n";
thread1.start();
The following output is guaranteed for every standard compliant C++ compiler (modulo addresses):
ThreadFunctor destroyed: 0000006E3ED6F6F0
before start
...
Furthermore the join operation only completes after the operation on the background thread has been completed, so because of the infinite loops your program won't terminate. You need some way of notifying the background threads to actually return instead of continuing forever.
Note that the standard library already contains the exact logic you're trying to implement here: std::thread or std::jthread for a implementation with builtin way of informing the background thread of a termination request.
int main()
{
using namespace std::chrono_literals;
int stackInt = 0;
int* heapInt = new int(0);
// every second each thread increments them, 0.5 s apart from each other
std::jthread thread1{ [=](std::stop_token stopToken, int& stackInt)
{
using namespace std::chrono_literals;
while (!stopToken.stop_requested())
{
std::this_thread::sleep_for(1s);
std::cout << "thread #1:" << std::endl;
stackInt += 1;
std::cout << "stack int: " << stackInt << " [" << &stackInt << "]" << std::endl;
*heapInt += 1;
std::cout << "heap int: " << *heapInt << " [" << heapInt << "]" << std::endl;
}
}, std::ref(stackInt) }; // thread started immediately
std::this_thread::sleep_for(10s);
thread1.request_stop();
thread1.join();
}
Why is the method payment1 giving a different outpout then payment2? payment2 has the same argument name then the method name (I hope I'm saying this right?). I mean that the code this->moneysamename+=moneysamename;. Why can't the compiler differentiate the 2 variables?
Here's the full code:
#include <iostream>
using namespace std;
class Person
{
protected:
static int money;
static int moneysamename;
public:
virtual void payment1(float money1) = 0;
virtual void payment2(float moneysamename) = 0;
};
class Worker : public Person
{
public:
virtual void payment1(float moneyanothername)
{
this->money+= moneyanothername;
cout << "Worker: " << money << endl;
};
virtual void payment2(float moneysamename)
{
this->moneysamename+= moneysamename;
cout << "Worker: " << moneysamename << endl;
};
};
void pay1(Person &m, float sum)
{
m.payment1(sum);
}
void pay2(Person &m, float sum)
{
m.payment2(sum);
}
int Person::money = 0;
int Person::moneysamename = 0;
int main()
{
Worker Gaston;
pay1(Gaston, 200);
pay1(Gaston, 300);
pay2(Gaston, 200);
pay2(Gaston, 300);
}
output:
Worker: 200
Worker: 500
Worker: 200
Worker: 300
Your problem is you are not printing the static variable in payment2 but instead you are printing the local function variable
cout << "Worker: " << moneysamename << endl;
Since in the above line you did not use this-> like you do in
this->moneysamename+= moneysamename;
You get the function local moneysamename and not the static member variable. Change the output to
cout << "Worker: " << this->moneysamename << endl;
and you will get the same output.
The reason you do not get this in payment1 is the function paramter has a different name then the static variable. Had you made the function
virtual void payment1(float money)
{
this->money+= money;
cout << "Worker: " << money << endl;
};
You would have had the same results.
virtual void payment2(float moneysamename)
{
this->moneysamename+= moneysamename;
cout << "Worker: " << moneysamename << endl;
};
Here inside payment2, moneysamename will always refer to the function's first argument by C++ scoping rules (the nearest definition is taken). Hence, always the function's argument will be printed instead of the static protected variable of the parent class with the same name.
To print the local parent's variable you have to go to it's scope by cout << "Worker: " << this->moneysamename << endl;
//function creating my class and thread
extractor = new FeatureExtractor(receiveBufferCurrent);
HANDLE hth1;
unsigned uiThread1ID;
hth1 = (HANDLE)_beginthreadex(NULL,
0,
FeatureExtractor::ThreadStaticEntryPoint,
extractor,
CREATE_SUSPENDED,
&uiThread1ID);
//Header file
class FeatureExtractor
{
private:
float sensorData[200][10];
public:
FeatureExtractor(float receiveBufferCurrent[][10]);
~FeatureExtractor();
//Thread for parallel input and motion detection
static unsigned int __stdcall ThreadStaticEntryPoint(void * pThis);
void ThreadEntryPoint();
void outputTest();
};
FeatureExtractor::FeatureExtractor(float receiveBufferCurrent[][10])
{
memcpy(sensorData, receiveBufferCurrent, sizeof(sensorData));
}
unsigned __stdcall FeatureExtractor::ThreadStaticEntryPoint(void * pThis)
{
FeatureExtractor * pthX = (FeatureExtractor*)pThis;
pthX->ThreadEntryPoint();
return 1;
}
void FeatureExtractor::ThreadEntryPoint()
{
outputTest();
}
//output function
for (int i = 0; i < 200; i = i + 50)
{
std::cout << "-------------------------------------------------------------------------" << std::endl;
std::cout << "AccelX=" << sensorData[i][1] << ", AccelY=" << sensorData[i][2] << ", AccelZ=" << sensorData[i][3] << std::endl;
std::cout << std::endl;
std::cout << "MagX=" << sensorData[i][4] << ", MagY=" << sensorData[i][5] << ", MagZ=" << sensorData[i][6] << std::endl;
std::cout << std::endl;
std::cout << "GyroX=" << sensorData[i][7] << ", GyroY=" << sensorData[i][8] << ", GyroZ=" << sensorData[i][9] << std::endl;
std::cout << std::endl;
std::cout << "-------------------------------------------------------------------------" << std::endl;
}
I have some problem with accessing the float array "sensorData" inside a thread.
If I output the sensorData array inside the constructor everything is fine but if I access the array from inside my thread my array just contains -1.58839967e+038 which I guess means that I cannot access my array in this way from a thread.
What am I doing wrong?
I got the thread code from a tutorial which accesses class member variables in the same way although just integers not multi dimensional arrays.
I tried to minimize the length of my code snippets while keeping the important parts, I'm thankful for anybody taking the time to analyze my code!
I found the solution myself now.
WaitForSingleObject(hth1, INFINITE);
Once I waited for my thread the issue has been resolved.
The issue occurred because I deleted my class before it could finish execution.
It also worked to simple remove the delete statement.
I need a way to generate a unique identifier (either string or integer) for any type for use in a set of template functions. The documentation for type_info::name() says it may or may not be different for different types, which worries me since I need to rely on them being unique. The hash_code probably isn't unique, either (judging by the name, I haven't looked at what the standard has to say on this).
My question mainly is, in what cases could typeid(T).name() be not unique?
Since types can come from different (DLL) modules, I can't simply use a global counter and a template static function. Thread safety isn't an issue though, since the functions that may require a type ID are guaranteed to only be called by one thread at a time.
I need a way to generate a unique identifier (either string or
integer) for any type for use in a set of template functions.
Would something along these lines help?
#include <cstdint>
#include <iostream>
using namespace std;
template <typename T>
class unique_id {
static char type_id;
public:
static uintptr_t get_ID() { return reinterpret_cast<uintptr_t>(&type_id); }
};
template <typename T>
char unique_id<T>::type_id;
struct { } s;
int main() {
cout << unique_id<int >::get_ID() << endl;
cout << unique_id<double >::get_ID() << endl;
cout << unique_id<decltype(s) >::get_ID() << endl;
cout << unique_id<size_t >::get_ID() << endl;
cout << unique_id<unsigned long>::get_ID() << endl;
}
There is something similar in the LLVM codebase as it doesn't use RTTI. However, I have failed to find the description of that trick. Even 30 minutes of googling didn't help; I have given up.
My question mainly is, in what cases could typeid(T).name() be not unique?
I don't know the answer to that one. My guess is that the standard doesn't mandate that; of course, it doesn't answer the questions why.
OK, see Michael J's answer.
UPDATE: As for std::type_info::name(), it seems like there is no guarantee by the standard; the returned string can be identical for several types and change between invocations of the same program.
One option is to dive into implementation defined land: I would simply test it on the types I care about and on all platforms and compiler that I care about. If it works fine then I would probably risk it.
However, there are std::type_info::operator== and std::type_info::operator!= which may solve your problem: You can distinguish types from each other and it even seems to be guaranteed. Does it matter in your application whether you compare strings or type_info objects?
Sometimes more than one name can refer to the same type. Hopefully the following example will give you the idea
#include <typeinfo>
#include <iostream>
int main()
{
class Foo
{
};
class Bar : public Foo
{
};
typedef int my_int;
std::cout << "int8_t = " << typeid(int8_t).name() << std::endl;
std::cout << "int16_t = " << typeid(int16_t).name() << std::endl;
std::cout << "int32_t = " << typeid(int32_t).name() << std::endl;
std::cout << "int64_t = " << typeid(int64_t).name() << std::endl;
std::cout << "short = " << typeid(short).name() << std::endl;
std::cout << "short int = " << typeid(short int).name() << std::endl;
std::cout << "int = " << typeid(int).name() << std::endl;
std::cout << "long = " << typeid(long).name() << std::endl;
std::cout << "long int = " << typeid(long int).name() << std::endl;
std::cout << "long long = " << typeid(long long).name() << std::endl;
std::cout << "long long int = " << typeid(long long int).name() << std::endl;
std::cout << "my_int = " << typeid(my_int).name() << std::endl;
std::cout << "Foo = " << typeid(Foo).name() << std::endl;
std::cout << "Bar = " << typeid(Bar).name() << std::endl;
return 0;
}
int8_t = signed char
int16_t = short
int32_t = int
int64_t = __int64
short = short
short int = short
int = int
long = long
long int = long
long long = __int64
long long int = __int64
my_int = int
Foo = ?AVFoo#?1?main#
Bar = ?AVBar#?1?main#
Just out of curiosity: if I have nested scopes, like in this sample C++ code
using namespace std;
int v = 1; // global
int main (void)
{
int v = 2; // local
{
int v = 3; // within subscope
cout << "subscope: " << v << endl;
// cout << "local: " << v << endl;
cout << "global: " << ::v << endl;
}
cout << "local: " << v << endl;
cout << "global: " << ::v << endl;
}
Is there any way to access the variable v with the value 2 from the "intermediate" scope (neither global nor local)?
You can declare a new reference as an alias like so
int main (void)
{
int v = 2; // local
int &vlocal = v;
{
int v = 3; // within subscope
cout << "local: " << vlocal << endl;
}
}
But I would avoid this practice this altogether. I have spent hours debugging such a construct because a variable was displayed in debugger as changed because of scope and I couldn't figure out how it got changed.
The answer is No You cannot.
A variable in local scope shadows the variable in global scope and the language provides a way for accessing the global variable by using qualified names of the global like you did. But C++ as an language does not provide anyway to access the intermediate scoped variable.
Considering it would have to be allowed it would require a lot of complex handling, Imagine of the situation with n number of scopes(could very well be infinite) and handling of those.
You are better off renaming your intermediate variables and using those that would be more logical and easy to maintain.
There are two types of scope resolution operators in C++ - unary scope and a class scope. There is no function scope or "any particular parent scope" resolution operators. That makes it impossible to solve your problem, as it is, in general because you cannot refer to anonymous scopes. However, you can either create an alias, rename variables, or make this a part of the class, which of course implies a code change. This is the closest I can get you without renaming in this particular case:
#include <iostream>
using namespace std;
int v = 1; // global
class Program
{
static int v; // local
public:
static int main ()
{
int v = 3; // within subscope
cout << "subscope: " << v << endl;
cout << "local: " << Program::v << endl;
cout << "global: " << ::v << endl;
}
};
int Program::v = 2;
int main ()
{
return Program::main ();
}
There are other ways, like making sure that variables are not optimized out and are on stack, then you can work with stack directly to get the value of the variable you want, but let's not go that way.
Hope it helps!
You could fake it like this:
#include <iostream>
using namespace std;
int v = 1;
int main()
{
int v = 2;
{
int &rv = v; // create a reference
int v = 3; // then shadow it
cout << "subscope: " << v << endl;
cout << "local: " << rv << endl;
cout << "global: " << ::v << endl;
}
cout << "local: " << v << endl;
cout << "global: " << ::v << endl;
return 0;
}
Interestingly this compiles on cygwin g++ but segfaults if you try to run it:
#include <iostream>
using namespace std;
int v = 1;
int main()
{
int v = 2;
{
int &v = v;
cout << "subscope: " << v << endl;
// cout << "local: " << v << endl;
cout << "global: " << ::v << endl;
}
cout << "local: " << v << endl;
cout << "global: " << ::v << endl;
return 0;
}