В отличие от Monitor, класс Mutex может использоваться для межпроцессной синхронизации. Для этого нужно использовать именованный мьютекс, который виден в операционной системе. Чтобы создать экземпляр именованного мьютекса, используйте конструктор Mutex, который задает имя. Также можно вызвать метод Mutex.OpenExisting, чтобы открыть существующий именованный системный мьютекс.
Думаю, этого достаточно для понимания различий.
Mutex это разве не тот же семафор, только который может брать один поток?
Нет, не тот же.
Как минимум, если говорить про .NET, то Mutex имеет одну фичу, которого нет у Semaphore:
Mutex можно использовать для синхронизации между процессами (при помощи именованного mutex) на Linux, а Semaphore нельзя.
На уровне ОС семафор и мутекс - это разные вещи. Предположу, что это позволяет немного оптимизировать реализацию, зная заранее, что у тебя будет только 1 поток, который его держит.