diff --git a/include/dynamic-graph/tracer.h b/include/dynamic-graph/tracer.h
index 9861b040b923bb829cbdbdcbcd140e064dfd1ef8..f5c23f265cdcde0a9593d512765a0668712cfe72 100644
--- a/include/dynamic-graph/tracer.h
+++ b/include/dynamic-graph/tracer.h
@@ -8,6 +8,7 @@
 #include <boost/function.hpp>
 #include <list>
 #include <string>
+#include <mutex>
 
 #include <dynamic-graph/entity.h>
 #include <dynamic-graph/exception-traces.h>
@@ -27,6 +28,7 @@ class DG_TRACER_DLLAPI Tracer : public Entity {
 protected:
   typedef std::list<const SignalBase<int> *> SignalList;
   SignalList toTraceSignals;
+  std::mutex files_mtx;
 
 public:
   enum TraceStyle {
diff --git a/src/traces/tracer-real-time.cpp b/src/traces/tracer-real-time.cpp
index ce7985d4cccac9a8b52ef7367aff8898ac1d37ab..70c4c12ba1a0f568c3289f4bdf5e531fac50cd40 100644
--- a/src/traces/tracer-real-time.cpp
+++ b/src/traces/tracer-real-time.cpp
@@ -146,6 +146,7 @@ void TracerRealTime::openFile(const SignalBase<int> &sig,
 
 void TracerRealTime::closeFiles() {
   dgDEBUGIN(15);
+  std::lock_guard<std::mutex> files_lock(files_mtx);
 
   FileList::iterator iter = files.begin();
   HardFileList::iterator hardIter = hardFiles.begin();
diff --git a/src/traces/tracer.cpp b/src/traces/tracer.cpp
index 99dadd76ab170331d523c683615e27abb5f16221..e43df731d6a8d9b8010a835c65dda137dbefffd1 100644
--- a/src/traces/tracer.cpp
+++ b/src/traces/tracer.cpp
@@ -171,6 +171,7 @@ void Tracer::openFile(const SignalBase<int> &sig, const string &givenname) {
 
 void Tracer::closeFiles() {
   dgDEBUGIN(15);
+  std::lock_guard<std::mutex> files_lock(files_mtx);
 
   for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) {
     std::ostream *filePtr = *iter;
@@ -193,6 +194,14 @@ void Tracer::record() {
 
   dgDEBUGIN(15);
 
+  // Ensure record() never hangs. If the attempt to acquire the lock fails,
+  // then closeFiles() is active and we shouldn't write to files anyways.
+  std::unique_lock<std::mutex> files_lock(files_mtx, std::try_to_lock);
+  if (!files_lock.owns_lock()) {
+    dgDEBUGOUT(15);
+    return;
+  }
+
   if (files.size() != toTraceSignals.size()) {
     DG_THROW
     ExceptionTraces(ExceptionTraces::NOT_OPEN, "No files open for tracing",