Vehicle-crossing simulation
As mentioned in the comments, there's not much to review.

Don't abuse using namespace std

Putting using namespace std within your program is generally a bad habit that you'd do well to avoid.  

Factor out common code

In this case, the code gets a lock, does something, and releases the lock.  That could easily be isolated to a common function:

class Locker
{
     pthread_mutex_t&amp;   mutex;
     bool               ok;
   public:
     operator bool() const {return ok;}

     Locker(pthread_mutex_t&amp; mutex)
         : mutex(mutex)
         , ok(true)
     {
         if(pthread_mutex_lock(&amp;mutex) != 0) {
             cerr &lt;&lt; "failed to lock output" &lt;&lt; endl;
             ok = false;
         }
     }
     ~Locker()
     {
         if (ok) {
             if(pthread_mutex_unlock(&amp;mutex) != 0) {
                 cerr &lt;&lt; "failed to unlock output" &lt;&lt; endl;
             }
         }
     }
};          
void report(Vehicle *v, const char *msg)
{
    Locker    lock(okToOutput);
    if (lock) {
        cout &lt;&lt; "Vehicle " &lt;&lt; v-&gt;licencePlate &lt;&lt; msg &lt;&lt; dirToStr(v-&gt;direction) &lt;&lt; endl;       
    }
}


To do this correctly, a failure to lock should exit the routine and not attempt to send output data.

Avoid C-style casts

Instead of (Vehicle *)arg use static_cast&lt;Vehicle *&gt;(arg).  It makes much more clear to humans reading your code what you're doing.