Multithreaded file IO?

Lutger Blijdestijn lutger.blijdestijn at gmail.com
Sun Sep 25 05:57:57 PDT 2011


Jerry Quinn wrote:

> Jonathan M Davis Wrote:
> 
>> On Saturday, September 24, 2011 01:05:52 Jerry Quinn wrote:
>> > Jonathan M Davis Wrote:
>> > > On Friday, September 23, 2011 23:01:17 Jerry Quinn wrote:
>> > > 
>> > > A direct rewrite would involve using shared and synchronized (either
>> > > on the class or a synchronized block around the code that you want to
>> > > lock). However, the more idiomatic way to do it would be to use
>> > > std.concurrency and have the threads pass messages to each other
>> > > using send and receive.
>> > 
>> > I'm trying the direct rewrite but having problems with shared and
>> > synchronized.
>> > 
>> > class queue {
>> >   File file;
>> >   this(string infile) {
>> >     file.open(infile);
>> >   }
>> >   synchronized void put(string s) {
>> >     file.writeln(s);
>> >   }
>> > }
>> > 
>> > queue.d(10): Error: template std.stdio.File.writeln(S...) does not
>> > match any function template declaration queue.d(10): Error: template
>> > std.stdio.File.writeln(S...) cannot deduce template function from
>> > argument types !()(string)
>> > 
>> > Remove the synchronized and it compiles fine with 2.055.
>> 
>> Technically, sychronized should go on the _class_ and not the function,
>> but I'm not sure if dmd is currently correctly implemented in that
>> respect (since if it is, it should actually be an error to stick
>> synchronized on a function). Regardless of that, however, unless you use
>> shared (I don't know if you are), each instance of queue is going to be
>> on its own thread. So, no mutexes will be necessary, but you won't be
>> able to have multiple threads writing to the same File. It could get
>> messy.
> 
> I get similar errors if I put synchronized on the class, or shared.  My
> best guess is that a File struct cannot currently (2.055) be shared or
> accessed in a synchronized context.
> 
> If I make the class synchronized and use __gshared on the File then it
> compiles.  I don't know if it works, though.

You could embed a File pointer in the synchronized queue, make sure it is 
the sole owner, and then cast to File* when using it. The concurrency 
chapter has a paragraph on this method that explains why it is not covered 
by the type system. 

I believe this is closest to your C++ example, I never did this though so 
I'm not 100% sure it works. 


More information about the Digitalmars-d-learn mailing list