Read only array of int thread safe ?

J

JAM

Donis Marshal book about C# language states that array access in C# is
not thread safe, but he does not elaborate on this to any detail. I
was wondering if it is not thread safe for all operations ? In my
program I have quite large array in main thread that I would like to
access from children threads for READ ONLY operation. My application
is solving a challenging puzzle by brute force and to speed up the
solver I have divided the task between available CPU cores using
threads. The problem is that to solve the puzzle they need to access
multiple times this array prepared beforehand in main thread. They all
will use read only access. I can't use lock statement because, that
would defy the intent of solving puzzle simultaneously in multiple
threads doing basically the same thing and certainly I would hate to
create copy of the same array for each thread, because it is quite
large.

Assuming, that read only access will turn out to be thread unsafe, is
StackAlloc and pointers another possible solution ?

Side question would be if StackAlloc and pointers (I'm guessing) are
not using boundary checking and are referring to memory directly
instead of through handle, should that have additional benefit of
slightly faster code ?

JAM.
 
J

Josh Einstein

Basically, arrays are not read-only because you can change the contents of
it. That's not to say that read-only use of an array is not thread-safe.

To guarantee protection of the array against writes, you could expose your
Int32[] as a IList<Int32> instead and wrap it in a ReadOnlyCollection<T>.
This doesn't change the thread safety of it, just protects it against
writes. If it's your own code it doesn't really matter.

private readonly int[] numbers;
private readonly ReadOnlyCollection<int> numbersReadOnly;

ctor() {
numbers = new [] { 0, 1, 2, 3, 4, 5 };
numbersReadOnly = new ReadOnlyCollection<int>(numbers);
}

public IList<int> Numbers {
get {
return numbersReadOnly;
}
}

Josh Einstein
 
J

JAM

Basically, arrays are not read-only because you can change the contents of
it. That's not to say that read-only use of an array is not thread-safe.

To guarantee protection of the array against writes, you could expose your
Int32[] as a IList<Int32> instead and wrap it in a ReadOnlyCollection<T>.
This doesn't change the thread safety of it, just protects it against
writes. If it's your own code it doesn't really matter.

private readonly int[] numbers;
private readonly ReadOnlyCollection<int> numbersReadOnly;

ctor() {
    numbers = new [] { 0, 1, 2, 3, 4, 5 };
    numbersReadOnly = new ReadOnlyCollection<int>(numbers);

}

public IList<int> Numbers {
   get {
     return numbersReadOnly;
   }

}

Josh Einstein


news:336c2e75-aebe-4348-8ea1-6d090f95aa54@z28g2000prd.googlegroups.com...

Josh

I think you misunderstood the essence of my question. I don't
particularly care about "read only" being guaranteed by software. I
write entire program myself, so I don't need any additional safety to
be built into the code and to be fair I've never cared in my life. I'm
a "sunday" programmer amatour for 30+ years and I never really cared
about "const" or "readonly" language enhacements in the past. I'm
probably now too old to change this "bad" behavior :) But back to
the point, the "read only" guarantee was not part of my question at
all. This is guaranteed by the program design.

My question was strictly about the thread safety of accesssing large
array for read only operation and about pure performance so I don't
want to use lock statment and I don't want to replace array with any
construction that might create performance penalty. Can two or more
threads access the same array for read only operation without using
lock statement ? I'm not sure if I understand your answer. Is read
only access of the array thread safe ?
How ReadOnlyCollection will improve my code beyong locking array into
read only wrapper which I don't care. Is the mentioned wrapper thread
safe ? Is it faster in performance over normal array ?

JAM
 
D

Dathan

Basically, arrays are not read-only because you can change the contentsof
it. That's not to say that read-only use of an array is not thread-safe..
To guarantee protection of the array against writes, you could expose your
Int32[] as a IList<Int32> instead and wrap it in a ReadOnlyCollection<T>.
This doesn't change the thread safety of it, just protects it against
writes. If it's your own code it doesn't really matter.
private readonly int[] numbers;
private readonly ReadOnlyCollection<int> numbersReadOnly;
ctor() {
    numbers = new [] { 0, 1, 2, 3, 4, 5 };
    numbersReadOnly = new ReadOnlyCollection<int>(numbers);

public IList<int> Numbers {
   get {
     return numbersReadOnly;
   }

Josh Einstein
"JAM" <[email protected]> wrote in message
news:336c2e75-aebe-4348-8ea1-6d090f95aa54@z28g2000prd.googlegroups.com....

Josh

I think you misunderstood the essence of my question. I don't
particularly care about "read only" being guaranteed by software. I
write entire program myself, so I don't need any additional safety to
be built into the code and to be fair I've never cared in my life. I'm
a "sunday" programmer amatour for 30+ years and I never really cared
about "const" or "readonly" language enhacements in the past. I'm
probably now too old to change this "bad" behavior :) But  back to
the point, the "read only" guarantee was not part of my question at
all. This is guaranteed by the program design.

My question was strictly about the thread safety of accesssing large
array for read only operation and about pure performance so I don't
want to use lock statment and I don't want to replace array with any
construction that might create performance penalty. Can two or more
threads access the same array for read only operation without using
lock statement ?  I'm not sure if I understand your answer. Is read
only access of the array thread safe ?
How ReadOnlyCollection will improve my code beyong locking array into
read only wrapper which I don't care. Is the mentioned wrapper thread
safe ? Is it faster in performance over normal array ?

JAM

The thread-safety warning about the Array class (and any classes that
derive from Array) is a warning that reads and writes aren't
synchronized. Reads don't change the internal state of the array, so
you can interleave as many as you want without worrying about
synchronizing them. You'll only run into problems if your threads
start writing to the array, at which point you'll need to use a lock,
Monitor, ReaderWriterLock, or some such device to ensure thread
safety.

~Dathan
 
J

JAM

The thread-safety warning about the Array class (and any classes that
derive from Array) is a warning that reads and writes aren't
synchronized.  Reads don't change the internal state of the array, so
you can interleave as many as you want without worrying about
synchronizing them.  You'll only run into problems if your threads
start writing to the array, at which point you'll need to use a lock,
Monitor, ReaderWriterLock, or some such device to ensure thread
safety.

~Dathan- Hide quoted text -

- Show quoted text -

Thanks Dathan.

I was worry, that boundary checking might somehow produce thread
issues and generate incorrect results in case when thread schedule
change will happen in the middle of boundary checking process.

But outside of my problem, which you have helped answer, what you have
written made me curious. I always thought that warning about thread
safety is that if two threads are accessing same object which is not
thread safe for some operation, one or both threads are risking to
obtain completely unpredictible effects such as garbage value, system
crash etc. Good example would be a function that is using static field
for some internal state storage. Such function clearly cannot be
reentered in parallel by second thread because single static field is
unable to hold two different states at the same time and would cause
garabge data for at least one thread if not both. In case of Array
that would be if one thread would be trying to read array value at
index 1 and the second thread would be writing at the same time some
value to the cell at index 2 and somehow value and index would get
mixed up during thread scheduling change such that value that was
destined for cell 2 ended up written to cell 1.If I understood you
correctly, this is not the case for Array. If two threads are accesing
the same array for read - write, then I'm risking that from time to
time I will get either old or new value of data in some array cell
that was modified by other thread but the value nonetheless will be
from the correct cell and correct old or new value. I'm surprised,
that Microsoft is considering this to be a lack of thread safety. For
me this is obvious side effect of parallel programming and
synchronizing access to the same object to achieve right time
dependency of variable. This in my mind is simply responsibility of
programmer. Am I simplifying the problem here ? If what you saying is
true, then Microsoft should consider even simple "int" field to be
considered thread unsafe if two threads are accessing it because one
might write some value to that filed and the other then would know if
the value obtained is up to date. This seem to me just not right :-(

JAM
 
P

Peter Morris

As long as the array is constructed and the data fully populated before any
of the worker threads start + the worker threads only read the data you will
be okay.
 
J

JAM

As long as the array is constructed and the data fully populated before any
of the worker threads start + the worker threads only read the data you will
be okay.

Thats exactly the case I'm planning to use. Thank you all for help and
explanation.

JAM
 
J

Josh Einstein

Let me restate it another way then.

The statement about arrays not being thread-safe is true. They are not
thread safe.

Multiple threads that only read from an array IS thread safe.

If you were creating a class that had a public property, it should not
expose an array directly and that is why I showed you the read-only wrapper.
I also said that if it was just your code using the array then it doesn't
matter what you do.

I didn't misunderstand your question, I just presented an alternative way of
doing what you're doing that is more guarded against bugs.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top