Is std::string thead-safe with gcc 4.3?
Threads are not yet part of the standard. But I don't think that any vendor can get away without making std::string thread-safe, nowadays. Note: There are different definitions of "thread-safe" and mine might differ from yours. Of course, it makes little sense to protect a container like std::vector for concurrent access by default even when you don't need it. That would go against the "don't pay for things you don't use" spirit of C++. The user should always be responsible for synchronization if he/she wants to share objects among different threads. The issue here is whether a library component uses and shares some hidden data structures that might lead to data races even if "functions are applied on different objects" from a user's perspective.
The C++0x draft (N2960) contains the section "data race avoidance" which basically says that library components may access shared data that is hidden from the user if and only if it activly avoids possible data races. It sounds like a copy-on-write implementation of std::basic_string must be as safe w.r.t. multi-threading as another implementation where internal data is never shared among different string instances.
I'm not 100% sure about whether libstdc++ takes care of it already. I think it does. To be sure, check out the documentation
std::string in a multi-threaded program
Given that the standard doesn't say a word about memory models and is completely thread unaware, I'd say you can't definitely assume every implementation will be non-cow so no, you can't
Apart from that, if you know your tools, most of the implementations will use non-cow strings to allow multi-threading.
std::string messed up when using it as storage within (boost.)async_read_some
Well, the problem wasn't Boost nor Boost::Asio. It was the method how I tested my application:
I used nc (Netcat) to test the performance and functions of my application with this command
nc localhost 4450 <testfile
where testfile contained a 36 characters long test string. Netcat wasn't only slow - it was the origin of this problem.
After I changed my strategy and coded a little boost::asio application to send the same requests to my application it worked. Fast, easy and without any problems.
I learned my lesson: Never use Netcat for stress tests again!
Return the Reference of a pass-by-reference parameter
Do not use a reference parameter to store output.
Simply create a local std::string inside the function and return it by value.
std::string toHexString( const uint8_t *buf, uint32_t size )
{
std::string out;
// modify 'out'
return out;
}
Due to compiler techniques such as Return Value Optimization, this should have similar performance, but much better semantics(no need for dummy extra parameter).
As far as thread safety goes the function is probably fine. You only need to worry about thread safety when data is shared between threads, and this function should not share any data.
How can I deploy a C++11 program (with dependencies) on CentOS 6, whose GCC is C++03?
Actually, you can distribute a program compiled with a newer g++ compiler on a vanilla CentOS 6 platform. There are several ways to do this: The easiest is to use the DevToolset 3, which will give you g++ 4.9.2 (the dev toolset 2 will give you gcc 4.8.2). Then, just compile your application with this g++. When distributing your software, you need to make sure to also ship the libstdc++.so
that is being shipped with g++ 4.9. Either set the LD_LIBRARY_PATH
so it gets picked up on startup, or set the RPATH to tell your executable where to look first for libraries.
Essentially, you can do this also with newer compilers, but then you first need to compile the compiler itself. If you don't want to compile a compiler first, go with a respective dev toolset and you should be fine.
Yes, you can also try to statically link libstdc++.a. Search for the option -static-libstdc++
:
When the g++ program is used to link a C++ program, it normally automatically links against libstdc++. If libstdc++ is available as a shared library, and the -static option is not used, then this links against the shared version of libstdc++. That is normally fine. However, it is sometimes useful to freeze the version of libstdc++ used by the program without going all the way to a fully static link. The -static-libstdc++ option directs the g++ driver to link libstdc++ statically, without necessarily linking other libraries statically.
But if you statically link, you will not get any security updates etc. Granted, you will not get the updates, if you ship libstdc++.so on your own as well, but incremental updates maybe easier.
And with respect to running your application: The rule of thumb is: Compile on the oldest platform you need to support, then your binaries (with self-shipped libstdc++ and other required libs) will likely work also on newer versions. That is, if you compile on CentoOS 6, and it works, then you can expect it to also work on CentOS 7. On a related subject, this is exactly the reason why for instance AppImage and related solutions recommend to build on an old system.
Why does c++ std::hash create a functor struct and can it be called without creating a struct each time
but I don't understand the actual reason a functor is even necessary in this context.
There is a good reasons why std::hash
is a functor and not a function and that is that it can have state. The C++ standard allows for salted hashes so that each execution of the same program can create different hashed values for the same original value.
Is it safe / correct to create one hash struct then call its operator() multiple different times?
std::hash<std::string> strHash;
strHash(data1);
strHash(data2);
Yes, that code is safe. You don't need to construct a hash
every time you want to hash something. It's okay to create a single hash object and use that for all of the hashes you need (in a singly threaded environment).
Is re-using one hash struct going to be threadsafe? And if not, how would I make it more threadsafe?
Depends on the use but most likely not. std::hash
has no thread safety guarantees so you need to protect the access to it using a mutex or some other synchronization technique. Or you could just use one hash object per thread as they are required to give the same output for the same input. This gives you a little extra space overhead but now you don't have any synchronization overhead which could be costly.
QT 4.3 passing class pointer between threads
"Does QT perform atomic operations on this class if it is composed of native types" - the language is C++, Qt just a library. Thus Qt doesn't do any magic when variables are accessed from multiple threads and the usual C++ multithreading rules and its memory model (since C++11) apply. The signal/slot mechanism however implements a message passing mechanism for inter-thread communication: Queued connections (see also the page on thread synchronisation) pass the arguments from one thread to another by copying them. I.e., passing value types such as QString, int, double is safe - the receiving thread will operate on a copy of the sending thread's data and there's no concurrent access that'd need locking. Signal/Slot arguments passed by const reference will also be copied by the signal/slot system.
However, if you pass pointers either as argument or contained in a struct, the pointer is copied, not the object it points to (in the case there's no custom copy ctor/assignment operator implementation doing otherwise). Thus, accessing the passed pointer is not safe for the and you'd need a synchronisation mechanism such as a mutex.
In your example, PORT_CHECK_STRUCT *portCheck
has this problem (when passing a PortInfo object), as well as void COM_DATA_UPDATE(const U_BYTE* msg)
. I'd suggest to pass the data via std::array (or std::vector/QVector if you can't use C++11).
Creating a class to store threads and calling them
The problem here is that you do not wait for the threads to end. In main
you create c
. This then spawns the threads. The next thing to happen is to return which destroys c
. When c
is destroyed it destroys its members. Now when a thread is destroyed if it has not been joined or detached then std::terminate
is called and the program ends
What you need to do is in the destructor, set running
to false
and then call join
on both the threads. This will stop the loop in each thread and allow c
to be destructed correctly.
Doing this however brings up another issue. running
is not an atomic variable so writing to it while threads are reading it is undefined behavior. We can fin that though by changing running to a std::atomic<bool>
which provides synchronization.
I also had to make a change to the thread construction. When you want to use a member function the syntax should be
std::thread(&class_name::function_name, pointer_to_instance_of_class_name, function_parameters)
so in this case it would be
threads.push_back(std::thread(&client::main, this));
threads.push_back(std::thread(&client::render, this));
Communication between threads via shared vector
std
data structures are not thread safe (for the most part) and therefore require additional synchronization if accessed by multiple threads simultaneously. In your case, one thread could be calling push_back
while another thread is calling erase
. This will produce undefined behavior. To fix this, both the push_back
and the erase
need to be protected by the same lock. I recommend you google for thread safety in the c++ standard library and read more about it.
Also, using a
vector
here is probably not the best choice. You should look into std::queue instead. When you erase
the first element of the vector
is has to copy all of the strings later in the vector down one, which can be very expensive. queue
does not suffer from this problem.
Related Topics
Is There a Reason Declval Returns Add_Rvalue_Reference Instead of Add_Lvalue_Reference
Are Mutex Lock Functions Sufficient Without Volatile
Quick and Dirty Way to Profile Your Code
Why Does Visual Studio Not Perform Return Value Optimization (Rvo) in This Case
How to Determine the Correct Size of a Qtablewidget
Is Using Increment (Operator++) on Floats Bad Style
Meaningful Stack Traces for Address Sanitizer in Gcc
Is Undefined Behavior Worth It
Static Constexpr' Function Called in a Constant Expression Is...An Error
How to Test If a Constexpr Function Is Evaluated at Compile Time
Convert Iso-8859-1 Strings to Utf-8 in C/C++
Implementing Component System from Unity in C++
Why Don't I Need to Specify "Typename" Before a Dependent Type in C++20
Sfinae and Partial Class Template Specializations
How to Do a C++ Style Compile-Time Assertion to Determine MAChine's Endianness
Weird Undefined Symbols of Static Constants Inside a Struct/Class
Difference Between Global Non-Throwing ::Operator New and Std::Malloc