Reputation: 322
Having two threads running simultaneously can give strange behavior when writing to and reading from a variable from both threads simultaneously. It can be thread safe, but is not in every case.
Thread safe example: TThread.Terminated
The Boolean Terminated just reads FTerminated, which is set only once and since it is a Boolean, the writing process is atomic. So the value can be read in the MainThread as well as in the thread and is always thread safe to read.
My example: I have a string, which is written only once. Unlike TThread.Terminated, the writing of my string is not atomic, so the reading of it is not thread safe per se. But there may be a thread safe way in a special case: I have a situation where I just want to compare the string to another string. I only do something if they are the same (and it's not critical if they are not equal because the string is just not completely written yet). So I thought about whether this may be thread safe or not. So what happens exactly when the string is written and what may go wrong if I read the string when it's only half way written?
Steps to be done when writing a string:
Under what circumstances is it safe to read the string which is written to in just this same moment?
Question to the ones who have such deep-knowledge: Are my assumptions true? If yes, can I rely on this safely? Or is it a such bad idea to rely on this implementation specifics that it's not even worth to think about all this and just not read strings unprotectedly when they are written to in another thread?
Upvotes: 0
Views: 1922
Reputation: 1440
Example of what could happen without any lock.
String is being written: it should become bigger than it was, so new memory is allocated. But pointer is not yet modified, it points to old string.
At the same time reading thread got a pointer and began to read old string.
Context switched again to writing thread. It changed pointer, so now it is valid. Old string got refcount 0 and was immediately freed.
Context switch again: reading thread continues to process old string, but now it is access to deallocated memory which may easily result in access violation.
Upvotes: 1
Reputation: 27493
Delphi strings are "thread-safe" only in a sense that a string's reference count is guarantied to be valid in a multithreaded code.
Copy-On-Write of Delphi strings is not a threadsafe operation; if you need a multithreaded read/write access to the same string you generally should use some synchronization, otherwise you are potentially in trouble.
Upvotes: 3