On Tue, 5 Jul 2016 02:38:28 -0700 (PDT) Pierre Durand <pierredur...@gmail.com> wrote:
> My code: https://play.golang.org/p/pg-p17UuEW > I'm trying to append lines to a file concurrently. > > My first write() function is buggy, because WriteString() are called > by several goroutines in unexpected order. > > So, I've written writeMutex(), that uses a mutex. > It works as expected, but in my real code, I'd prefer to avoid mutex. > (in my real code write() can write to different files; the file's > name is given as argument) > > I've also written writeBuffer(). > Is it OK to call f.Write() 1 time from several goroutines? > It looks like it works, but I'm not 100% sure this is correct. It's hard for me to discern your real problem from your statement, but I'll do a shot in the dark: if your concern is that having a single mutex will possibly create unnecessary contention when writing in separate files, just have a separate mutex per file. If the entry point to your writing machinery receives the file's name as its argument, have a map which assigns mutexes to file names. Be sure to also delete the matching entry from this map when a particular file is finished dealing with. You might also consider a different approach. Say, you might have a manager goroutine running forever and doing two things: maintaining a list of active file writes and an input channel receiving tasks in the form of tuples (file_name, data_to_write). If it detects there's no in progress write operation happens for the file from the next task, it spawns a goroutine writing data to that file and creates an entry in its internal map marking that file as "busy". It then waits for the signal of that working goroutine that it has finished work and removes the "busy mark". Yet another approach is to have such manager goroutine fork a long-running worker goroutine per named file: from each incoming task it fetches the file's name and submits its data to write to appropriate worker goroutine on a dedicated channel. But before you "go parallel" take into account that writing data to files is an I/O-bound operation and if your files reside on the same filesystem (and especially if that filesystem is backed by rotating medium), or on different filesystem backed by the same meduim, you probably won't get the speedup you're seeking: the write operations will be naturally serialized "back" by the filesystem layer of your OS. Hence rather than have N "parallel" writes been stalled waiting on the OS to cope with them, it might have more sense to just have a single dedicated writing goroutine which will receive "writing tasks" (see above) and perform they in FIFO order. To reiterate: being able to perform certain operations in parallel or concurrently is cool but always keep in mind that after "leaving" the runtime they hit CPU and OS where things suddenly stop being "pure", theoretical and ideal. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.