Should I use a CriticalSection on WriteFile calls?

Posted on 2010-11-08
Last Modified: 2013-12-27
I have an application in Windows CE that creates multiple threads that can at any time make a call to a log function that uses a WriteFile call. Should I use a CriticalSection around the WriteFile call and/or all the internals of the api that uses the WriteFile function or does WriteFile handle the proper sequence when multiple threads call it?

Question by:atomicgs12
LVL 86

Accepted Solution

jkr earned 167 total points
ID: 34086599
>>does WriteFile handle the proper sequence when multiple threads call it?

In simple words: Since all Windows APIs are reentrant, it is safe to assume that this one is, too. You have to take care of synchronizing access to a file yourself, so a critical section is actually a good solution.
LVL 31

Assisted Solution

Frosty555 earned 166 total points
ID: 34086658
I would not count on WriteFile handling race conditions for you. Assuming you have opened the file for writing once in your application, and all of your threads reference the same shared file handler, then yes you need a critical section.

If you have each thread independently creating new file handles with OpenFile() each time they want to write to the logfile, then the situation is slightly different. In this case, when one thread opens the file it will lock it for writing. If another thread  tries to open the same file it will fail with an "access denied" error because the file is in use. Critical sections will also help fix this, but proper error handling in the event of not being able to open the file for any reason (not enough disk space, file doesn't exist, hanging file handler from an old process etc.) is still necessary.


Assisted Solution

JimBeveridge earned 167 total points
ID: 34086985
Calling WriteFile() from multiple threads isn't going to crash Windows (or even crash your process), but there's no guarantee that data will be written in the desired order, or whether a particular data block will be written atomically. So you can end up with a mess.

Opening a file handle when your app starts and then writing from different threads using critical sections is a fine solution. The only downside is that you may need to flush the data after each write so that no data wil be lost if your app crashes.

If you open and close the file for each write to the log, Frosty555 is correct that you can rely on file sharing to prevent you from accessing the file, but there's no way to be automatically notified when the file becomes available. The only solution is to continually retry opening the file and sleep between each attempt. Not a great solution unless it's just debug code. Far better to use a critical section.

Alternatives for logging that avoid contention problems:
- Make each thread write to a separate file where each new entry has a timestamp, then merge the files later.
- Create a dedicated thread for logging and that thread is the only thread that writes to the file. Bump its priority to make sure it runs often enough. You can send data to it using a FIFO queue protected with a critical section.

Author Comment

ID: 34087321
These are all good answers. I never know how to give out points. jkr was first with an answer but Frosty555 and JimDeveridge both gave additional useable commnets. What do you guys suggest?

Expert Comment

ID: 34087335
You can split the points as you see fit. You don't have to award all of the points to one person.

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Migrating From Parse To AWS 8 165
Task manager indicates my c++ program memory consumption is growing? 12 123
Create a path if not exists 7 90
C++ Code Issue 4 25
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
With Windows Embedded Handheld, called Windows Mobile, Microsoft re-designed the user interface. The Start Icon moved down to the bottom, inside the menu bar area.   If you need to hide the Start Icon and/or the SIP (soft input panel, softwar…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question