At the University of Arizona, we implemented in our class projects various stages of an operating system kernel, such as a process/thread scheduler, user/kernel mode functions, message passing (IPC/mailboxes), locking/semaphores/mutexes, signals, paged memory, and a file system in this upper division course. It wasn't as hard as a class like Automata, but it was tedious.
However, now that I am doing so much low level work, I can appreciate what we learned in class. In fact, it gives you a strong understanding how critical sections and locking work (and how this all ties in with the operating system). It makes you appreciate simple user mode delegate syscalls like fopen, fork, and malloc and realize that a bunch of things are happening in kernel mode. It makes you avoid naive design choices like while(true) loops and look for blocking/event-based equivalents.
So you might groan about taking an operating systems class. Don't! You might never ever work on operating systems, but you will be able to appreciate how to make the operating system work for you. Some self taught programmers I have met don't know the difference between blocking and non-blocking. If anything, operating systems will drill these concepts into your head to help you leverage operating systems for your benefit.