Dipende dell'implementazione di fprintf... Che io sappia sia glibc che la CRT Microsoft hanno un lock gestito automaticamente nelle operazioni su FILE *, per cui non dovrebbe essere necessario, in caso contrario effettivamente la critical section servirebbe.

Riguardo alla versione precedente, mi sono dimenticato di dire che è vero che non c'è rischio di stato incoerente a livello di strutture dati del tuo programma, ma visto che tutti pasticciano lo stesso file in contemporanea il suo contenuto in un dato momento non è deterministico (a seconda di come vengono ordinate le fopen, le scritture dei buffer, eccetera). In questo la situazione è perfettamente analoga all'avere più processi che lavorano insieme sullo stesso file senza sincronizzazione.