Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Are static functions without static variables thread-safe? Is there a website that lists what C/C++ functions are not thread-safe?

For example,

MSIL
static void Split_Into_Path_And_File(char * const SaveAs,
                                     std::string & Path,
                                     std::string & File) {
    std::string const temp(SaveAs);
    //find the folder name to use to name the 7z file
    size_t last=temp.find_last_of('\\');
    File=temp.substr(last+1, temp.size()-last-1);
    Path=temp.substr(0, last);
}


Am I correct assuming that static function constants (not in classes) and constant arrays thread-safe as well?

For example,

static int const X=5;
static Increment[WEEKDAYS_IN_WEEK+WEEKDAYS_IN_WEEK]= { 1, 1, 1, 1, 3, 1, 1, 1, 1, 3 };


I am trying to figure out why my ADO .NET code with _stdcall interface massively leaks memory when called with multiple threads from multi-threaded exe without run-time support.
Posted
Updated 21-Sep-10 4:40am
v3

It depends on how they're written. If you do everything carefully you can get away with it. However you really have to link with the multi-threaded runtime or it can all end in tears. Seeing as with C++ you haven't been able to use a single threaded runtime since 2005 with VC++ maybe a compiler upgrade is in order?

In the example you've given you're potentially allocating memory in three out of four lines in that function - if you're not linking with the multi-threaded runtime you can easily end up with problems when:

- the standard string constructor or assignment operator uses the same block of memory for two different objects (something will probably crash)

- two strings in different threads go out of scope at the same time, the last one to free the memory sticks and the second is lost

So make sure that you use the mutithreaded runtime, don't share objects between threads or make sure they're properly synchronised.

Cheers,

Ash

PS: With respect to the "answer" you gave below - the function above is not thread safe. If two threads enter it at the same time chaos may (or not) ensue. If you want to make it thread safe either do what Paul suggested and get rid of the reference parameters OR lock the function so only one thread can be in it at one time. I'd do what Paul suggested as locking in this sort of case can really burn any parallel speedup for your code.
 
Share this answer
 
v2
Wait a second... Accessing the objects Path and File is by no means thread-safe. It depends on whether several threads may share these instances or not.

A thread safe version would be this one, for example (of course under the assumption you are using a thread safe version of the runtime lib):
static std::pair<std::string, std::string>
Split_Into_Path_And_File
( char * const SaveAs ) {
    std::string const temp(SaveAs);
    //find the folder name to use to name the 7z file
    size_t last=temp.find_last_of('\\');
    return std::make_pair(
     temp.substr(last+1, temp.size()-last-1);
     temp.substr(0, last));
}


Edited by Ash to get rid of the redundant extra parameter to the function
 
Share this answer
 
v3
Comments
T2102 22-Sep-10 0:25am    
I am running several threads at once. Can you tell me why is passing in std::string & Path and std::string & File in a void function is not thread-safe? I will check if I am using fopen elsewhere and whether that is thread-safe.
Paul Michalik 22-Sep-10 18:03pm    
Because both are references to objects which are "non-local" from the function's perspective. If this function is executed concurrently by different threads you might get a race condition when writing to Path and/or File. With the above version, only a thread local (stack) object is generated, hence it's thread safe.
Glad that I am using Visual Studio 2010 then. Thanks for letting me know that the above function should be thread safe as long as I use multi-threaded run-time.
 
Share this answer
 
you can use CriticalSection,
for example, if you use MFC, the code may like below:
MSIL
<pre lang="cs">#include "afxmt.h"

CCriticalSection critical_section;

static void Split_Into_Path_And_File(char * const SaveAs,
std::string & Path,
std::string & File)
{
std::string const temp(SaveAs);
critical_section.Lock();
//find the folder name to use to name the 7z file
size_t last=temp.find_last_of('\\');
File=temp.substr(last+1, temp.size()-last-1);
Path=temp.substr(0, last);
critical_section.Unlock();
}
 
Share this answer
 
This function is thread-unsafe just like any other C/C++ function that takes reference or pointer. The function atoi, for example is prone to multi-threading issues.
 
Share this answer
 
Comments
Aescleal 27-Sep-10 15:42pm    
So if I write a function:

void f( A &a )
{
a.do_something();
a.do_something_else();
}

How can you tell that's unsafe without examining the code for A? While you can say "Aliasing data between threads is a good way of causing threading issues" saying a function can't be thread safe because it takes a reference or pointer is completely specious.
Ajay Vijayvargiya 27-Sep-10 22:58pm    
char buffer[10]; // Global
...
// thread 1.
int n1 = atoi(buffer);

// thread 2
int n2 = atoi(buffer);

Isn't it thread-unsafe? This is the whole point. Unless you guard the function or the object yourself, it is unsafe!
Paul Michalik 28-Sep-10 2:15am    
No, it's not since atoi is read-only operation.. Writing to 'buffer' is inherently thread unsafe. You cannot generalize that to the above statement. In Ash's example, A::do_something could be designed to be thread safe. The function from the first example is not safe if looking at it alone: the assignment to a std::string& is not thread-safe. However, if used in thread local context it could be safe to use it, for example:

class A {
private:
void Split_Into_Path_And_File(...);
//...
public:
void DoWork() {

ThreadPool.StartNew([] -> (const char* str) {
std::string p, f;
Split_Into_Path_And_File(str, p, f);
DoSomethingThreadSafe(p, f);
});
}
}; // A end

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900