I have the following code with private static members.
All of these classes say that they are thread safe in the MSDN library for "public static" members.
My question is whether these members will be thread safe when used as private static instead of "public static" as stated in the MSDN library.
public static class passwordManager
{
private static System.Security.Cryptography.SHA256 shaM = new System.Security.Cryptography.SHA256Managed();
private static System.Security.Cryptography.RandomNumberGenerator rand = new System.Security.Cryptography.RNGCryptoServiceProvider();
private static System.Text.Encoding enc = System.Text.Encoding.ASCII;
public static string produceSalt(int size)
{
byte[] by = new byte[size];
lock (rand)
{
rand.GetBytes(by);
}
return enc.GetString(by, 0, by.Length);
}
public static string encryptPassword(string password, string salt){
return enc.GetString(shaM.ComputeHash(enc.GetBytes(password + salt)));
}
public static bool isCorrectPassword(string inputPassword, string DBsalt, string DBpassword)
{
return encryptPassword(inputPassword, DBsalt) == DBpassword;
}
This might be entirely dependent on whether the methods I am using themselves use shared variables instead of all method instance variables... some peace of mind would be helpful but I would rather not have to lock everything here if it isn't necessary.
The only reason I locked the random number generator is to limit the possibility of getting the same salt however the chances of this being called by two threads at the same time is very low in my situation.
Thanks,
Mike
This should now be thread safe. I was trying to save on object instantiation overhead but I guess there is a trade off between this and lock waiting. On a high load system lock waiting would likely greatly overpower instantiation overhead and memory usage.
public static class passwordManager
{
private static System.Security.Cryptography.RandomNumberGenerator rand = new System.Security.Cryptography.RNGCryptoServiceProvider();
public static byte[] produceSalt(int size)
{
byte[] by = new byte[size];
lock (rand)
{
rand.GetBytes(by);
}
return by;
}
public static byte[] encryptPassword(string password, byte[] salt){
System.Security.Cryptography.SHA256 shaM = new System.Security.Cryptography.SHA256Managed();
System.Text.Encoding enc = new System.Text.UTF8Encoding();
return shaM.ComputeHash(concatArrays(enc.GetBytes(password), salt));
}
public static bool isCorrectPassword(string inputPassword, byte[] DBsalt, byte[] DBpassword)
{
return compare(encryptPassword(inputPassword, DBsalt), DBpassword);
}
}
Your code is not thread-safe.
Consider the System.Text.Encoding variable enc. You are calling GetString which is an instance member. The documentation says that only public static members are thread-safe so by inference GetString is not thread-safe because it is not a public static member.1
This code may fail due to the following reasons:
You have made no attempt to synchronize access to Encoding.GetString.
Encoding.GetString is called from a public static method in your passwordManager class.
Public static methods have a high probability of being executed by multiple threads simultaneously.
The reason why public static methods are almost always designed to be thread-safe is because it would be awkward for the caller to always synchronize access to it. You cannot limit multithreaded access to static members like you can with instance members. Consider an ASP.NET application, for example. Web page requests are frequently handled concurrently on separate threads. Do you want to use a lock everytime you call a static method? Of course not. This is a ridiculous burden to place on a developer.
Update:
Your new code is now thread-safe. You will have to do some benchmark tests to see which way is faster: using a lock or instantiating new instances on every call like you have now. I would not be surprised if the lock were faster.
1The same could be said for shaM.ComputeHash and enc.GetBytes.
thread safety won't depend on whether something is private or public.
BTW, thread safety document says any public static members of this type, not when this type is embedded as public static.
In short you have to lock your fields like sham, if you are multi-threading.
You might be better off creating method level variables instead of trying to make synchronise access to shared private fields. That way you will still achieve concurrency as each thread has it's own call stack so will have separate instances of each object and thus allow multiple threads to execute the method simultaneously. If you lock on a shared object then only one thread can execute the method at a time. Another option may be to use the [ThreadStatic] attribute on each field so they will not be shared across threads.
Related
i have the following static class with generic methods and i'm wondering if it's safe to use it from different threads and with different objects? i'm not sure how this works below the covers so an explanation of would help
public static class Serialization
{
public static byte[] Serialize<T>(T obj)
{
using (var ms = new MemoryStream())
{
Serializer.SerializeWithLengthPrefix<T>(ms, obj, PrefixStyle.Base128);
return ms.ToArray();
}
}
public static T DeSerialize<T>(byte[] bytes)
{
using (var ms = new MemoryStream(bytes))
{
return Serializer.DeserializeWithLengthPrefix<T>(ms, PrefixStyle.Base128);
}
}
}
The only problem with threads is accessing the same object from different threads without synchronization.
If each function only uses parameters for reading and local variables, they don't need any synchronization to be thread-safe.
It follows the convention that static methods should be thread-safe, but actually in v2 that static api is a proxy to an instance method on a default instance: in the case protobuf-net, it internally minimises contention points, and synchronises the internal state when necessary. Basically the library goes out of its way to do things right so that you can have simple code.
I have 1 static class and 1 field and 2 methods within it:
static class MyClass{
private static HttpClient client = new HttpClient();
private static string SendRequestToServer(int id)
{
Task<HttpResponseMessage> response = client.GetAsync("some string");
responseTask.ContinueWith(x => PrintResult(x));
return "some new value";
}
private static void Print(Task<HttpResponseMessage> task)
{
Task<string> r = task.Result.Content.ReadAsStringAsync();
r.ContinueWith(resultTask => Console.WriteLine("result is: " + resultTask.Result));
}
}
The question is, if many threads start using MyClass and its methods, would it cause some problems?
All the resources accessed through these methods need to be thread-safe. In your case, they are not. If you look at the HttpClient documentation, it states:
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
You're calling an instance method (client.GetAsync), which is not be guaranteed to be thread-safe, so that could potentially cause problems for you.
To mitigate this, you could:
create a new (local) HttpClient on each call.
synchronize access to client (e.g. using a lock).
Also, I can't tell you if PrintResult will be thread-safe, but Console.WriteLine should be thread-safe.
You are likely to expect unpredictable results with such setup.You need to have threads access the data in a synchronized manner.A lock statement need to used in your case to make sure the execution happens in a synchronized and stable manner.
private static Object locker= new Object();
private static string SendRequestToServer(int id)
{
lock(locker)
{
Task<HttpResponseMessage> response = client.GetAsync("some string");
responseTask.ContinueWith(x => PrintResult(x));
return "some new value";
}
}
I need to make a critical section in an area on the basis of a finite set of strings. I want the lock to be shared for the same string instance, (somewhat similar to String.Intern approach).
I am considering the following implementation:
public class Foo
{
private readonly string _s;
private static readonly HashSet<string> _locks = new HashSet<string>();
public Foo(string s)
{
_s = s;
_locks.Add(s);
}
public void LockMethod()
{
lock(_locks.Single(l => l == _s))
{
...
}
}
}
Are there any problems with this approach? Is it OK to lock on a string object in this way, and are there any thread safety issues in using the HashSet<string>?
Is it better to, for example, create a Dictionary<string, object> that creates a new lock object for each string instance?
Final Implementation
Based on the suggestions I went with the following implementation:
public class Foo
{
private readonly string _s;
private static readonly ConcurrentDictionary<string, object> _locks = new ConcurrentDictionary<string, object>();
public Foo(string s)
{
_s = s;
}
public void LockMethod()
{
lock(_locks.GetOrAdd(_s, _ => new object()))
{
...
}
}
}
Locking on strings is discouraged, the main reason is that (because of string-interning) some other code could lock on the same string instance without you knowing this. Creating a potential for deadlock situations.
Now this is probably a far fetched scenario in most concrete situations. It's more a general rule for libraries.
But on the other hand, what is the perceived benefit of strings?
So, point for point:
Are there any problems with this approach?
Yes, but mostly theoretical.
Is it OK to lock on a string object in this way, and are there any thread safety issues in using the HashSet?
The HashSet<> is not involved in the thread-safety as long as the threads only read concurrently.
Is it better to, for example, create a Dictionary that creates a new lock object for each string instance?
Yes. Just to be on the safe side. In a large system the main aim for avoiding deadlock is to keep the lock-objects as local and private as possible. Only a limited amount of code should be able to access them.
I'd say it's a really bad idea, personally. That isn't what strings are for.
(Personally I dislike the fact that every object has a monitor in the first place, but that's a slightly different concern.)
If you want an object which represents a lock which can be shared between different instances, why not create a specific type for that? You can given the lock a name easily enough for diagnostic purposes, but locking is really not the purpose of a string. Something like this:
public sealed class Lock
{
private readonly string name;
public string Name { get { return name; } }
public Lock(string name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
this.name = name;
}
}
Given the way that strings are sometimes interned and sometimes not (in a way which can occasionally be difficult to discern by simple inspection), you could easily end up with accidentally shared locks where you didn't intend them.
Locking on strings can be problematic, because interned strings are essentially global.
Interned strings are per process, so they are even shared among different AppDomains. Same goes for type objects (so don't lock on typeof(x)) either.
I had a similar issue not long ago where I was looking for a good way to lock a section of code based on a string value. Here's what we have in place at the moment, that solves the problem of interned strings and has the granularity we want.
The main idea is to maintain a static ConcurrentDictionary of sync objects with a string key. When a thread enters the method, it immediately establishes a lock and attempts to add the sync object to the concurrent dictionary. If we can add to the concurrent dictionary, it means that no other threads have a lock based on our string key and we can continue our work. Otherwise, we'll use the sync object from the concurrent dictionary to establish a second lock, which will wait for the running thread to finish processing. When the second lock is released, we can attempt to add the current thread's sync object to the dictionary again.
One word of caution: the threads aren't queued- so if multiple threads with the same string key are competing simultaneously for a lock, there are no guarantees about the order in which they will be processed.
Feel free to critique if you think I've overlooked something.
public class Foo
{
private static ConcurrentDictionary<string, object> _lockDictionary = new ConcurrentDictionary<string, object>();
public void DoSomethingThreadCriticalByString(string lockString)
{
object thisThreadSyncObject = new object();
lock (thisThreadSyncObject)
{
try
{
for (; ; )
{
object runningThreadSyncObject = _lockDictionary.GetOrAdd(lockString, thisThreadSyncObject);
if (runningThreadSyncObject == thisThreadSyncObject)
break;
lock (runningThreadSyncObject)
{
// Wait for the currently processing thread to finish and try inserting into the dictionary again.
}
}
// Do your work here.
}
finally
{
// Remove the key from the lock dictionary
object dummy;
_lockDictionary.TryRemove(lockString, out dummy);
}
}
}
}
By default non-static methods have their own instance of variables for each thread when accessed via multiple threads, thus rendering them thread safe if they do not include a public variable etc.
On the other hand, variables in static methods are shared amongst threads rendering them non-thread safe by default.
Say, I have a class, having no static variables or methods whatsoever.
public class Profile {
private ConcurrentDictionary<int, int> cache =
new ConcurrentDictionary<int, int>();
public AddToCache() {
}
public RemoveToCache() {
}
public DoSomethingThatShouldBeThreadSafe() {
}
}
But then I create a static object from this class.
public static Profile objProfile = new Profile();
And then, objProfile is accessed with multiple threads.
The question is, are the methods of Profile class, AddToCache, RemoveFromCache and DoSomethingThatShouldBeThreadSafe, going to be thread safe or not when used through objProfile? Are their variables will be shared amongst threads, even if they are not static because the whole instance of the class is static?
As long as you only access the ConcurrentDictionary<> instance cache, and don't overwrite cache with a new instance in one of Profile-methods it is threadsafe.
Because of the second point, it's better to mark it readonly,
private readonly ConcurrentDictionary<int, int> cache =
new ConcurrentDictionary<int, int>();
because this says that you can write this member only during instantiation of Profile.
EDIT:
Although the ConcurrentDictionary<> itself is thread-safe, you still have the problem of non-atomicity of compound operations. Let's take a look at two possible GetFromCache() methods.
int? GetFromCacheNonAtomic(int key)
{
if (cache.ContainsKey(key)) // first access to cache
return cache[key]; // second access to cache
return null;
}
int? GetFromCacheAtomic(int key)
{
int value;
if (cache.TryGetValue(key, out value)) // single access to cache
return value;
return null;
}
only the second one is atomic, because it uses the ConcurrentDictionary<>.TryGetValue() method.
EDIT 2 (answer to 2nd comment of Chiao):
ConcurrentDictionary<> has the GetOrAdd() method, which takes a Func<TKey, TValue> delegate for non-existing values.
void AddToCacheIfItDoesntExist(int key)
{
cache.GetOrAdd(key, SlowMethod);
}
int SlowMethod(int key)
{
Thread.Sleep(1000);
return key * 10;
}
You seem to me to be asserting that local variables of a static method are themselves static. This is not true.
Local variables are always local for both instance and static methods and so, excluding special cases like variable capture, live on the stack. Thus they are private to each separate invocation of the method.
Yes this should be a thread safe setup. All the functions will create their own 'copy' of the function local variables. Only when you explicitly 'touch' shared properties you'll get into problems.
However there will be only ONE cache, making the containing class static will make touching the cache NOT thread safe.
Okay, newbie multi-threading question:
I have a Singleton class. The class has a Static List and essentially works like this:
class MyClass {
private static MyClass _instance;
private static List<string> _list;
private static bool IsRecording;
public static void StartRecording() {
_list = new List<string>();
IsRecording = true;
}
public static IEnumerable<string> StopRecording() {
IsRecording = false;
return new List<string>(_list).AsReadOnly();
}
public MyClass GetInstance(){
}
public void DoSomething(){
if(IsRecording) _list.Add("Something");
}
}
Basically a user can call StartRecording() to initialize a List and then all calls to an instance-method may add stuff to the list. However, multiple threads may hold an instance to MyClass, so multiple threads may add entries to the list.
However, both list creation and reading are single operations, so the usual Reader-Writer Problem in multi-threading situations does not apply. The only problem I could see is the insertion order being weird, but that is not a problem.
Can I leave the code as-is, or do I need to take any precautions for multi-threading? I should add that in the real application this is not a List of strings but a List of Custom Objects (so the code is _list.Add(new Object(somedata))), but these objects only hold data, no code besides a call to DateTime.Now.
Edit: Clarifications following some answers: DoSomething cannot be static (the class here is abbreviated, there is a lot of stuff going on that is using instance-variables, but these created by the constructor and then only read).
Is it good enough to do
lock(_list){
_list.Add(something);
}
and
lock(_list){
return new List<string>(_list).AsReadOnly();
}
or do I need some deeper magic?
You certainly must lock the _list. And since you are creating multiple instances for _list you can not lock on _list itself but you should use something like:
private static object _listLock = new object();
As an aside, to follow a few best practices:
DoSomething(), as shown, can be static and so it should be.
for Library classes the recommended pattern is to make static members thread-safe, that would apply to StartRecording(), StopRecording() and DoSomething().
I would also make StopRecording() set _list = null and check it for null in DoSomething().
And before you ask, all this takes so little time that there really are no performance reasons not to do it.
You need to lock the list if multiple threads are adding to it.
A few observations...
Maybe there's a reason not to, but I would suggest making the class static and hence all of its members static. There's no real reason, at least from what you've shown, to require clients of MyClass to call the GetInstance() method just so they can call an instance method, DoSomething() in this case.
I don't see what prevents someone from calling the StartRecording() method multiple times. You might consider putting a check in there so that if it is already recording you don't create a new list, pulling the rug out from everyone's feet.
Finally, when you lock the list, don't do it like this:
static object _sync = new object();
lock(_sync){
_list.Add(new object(somedata));
}
Minimize the amount of time spent inside the lock by moving the new object creation outside of the lock.
static object _sync = new object();
object data = new object(somedata);
lock(_sync){
_list.Add(data);
}
EDIT
You said that DoSomething() cannot be static, but I bet it can. You can still use an object of MyClass inside DoSomething() for any instance-related stuff you have to do. But from a programming usability perspective, don't require the users to MyClass to call GetInstance() first. Consider this:
class MyClass {
private static MyClass _instance;
private static List<string> _list;
private static bool IsRecording;
public static void StartRecording()
{
_list = new List<string>();
IsRecording = true;
}
public static IEnumerable<string> StopRecording()
{
IsRecording = false;
return new List<string>(_list).AsReadOnly();
}
private static MyClass GetInstance() // make this private, not public
{ return _instance; }
public static void DoSomething()
{
// use inst internally to the function to get access to instance variables
MyClass inst = GetInstance();
}
}
Doing this, the users of MyClass can go from
MyClass.GetInstance().DoSomething();
to
MyClass.DoSomething();
.NET collections are not fully thread-safe. From MSDN: "Multiple readers can read the collection with confidence; however, any modification to the collection produces undefined results for all threads that access the collection, including the reader threads." You can follow the suggestions on that MSDN page to make your accesses thread-safe.
One problem that you would probably run into with your current code is if StopRecording is called while some other thread is inside DoSomething. Since creating a new list from an existing one requires enumerating over it, you are likely to run into the old "Collection was modified; enumeration operation may not execute" problem.
The bottom line: practice safe threading!
It's possible, albeit tricky, to write a linked list that allows simultaneous insertions from multiple threads without a lock, but this isn't it. It's just not safe to call _list.Add in parallel and hope for the best. Depending how it's written, you could lose one or both values, or corrupt the entire structure. Just lock it.