Binary vs process
A Go binary sitting on disk is just a file:
When you run it:
the OS creates a process.
A process is mainly a container for things like memory, files, sockets, and threads.
2. Every running process needs at least one OS thread
A generic process can be as simple as:
The thread is the actual execution unit that the OS schedules.
The process itself is not what directly runs on a core.
3. Go adds another layer: goroutines
A Go process has the Go runtime inside it.
Important point:
main() itself runs as the main goroutine.
Even if you never write:
Go still has internal goroutines for runtime work such as GC and scheduling.
4. Goroutine is not an OS thread
A goroutine is a lightweight user-space execution unit.
You can casually think:
But technically:
Many goroutines are scheduled onto a smaller number of OS threads:
Creating:
does not mean:
Usually it just creates another goroutine for the Go scheduler to manage.
5. One OS thread executes one goroutine at a time
Suppose several goroutines can use Thread 1:
That does not mean all four run simultaneously on Thread 1.
It means over time:
Go switches which goroutine is running.
And goroutines are generally not permanently attached to a specific OS thread.
For example:
Goroutine A moved.
6. OS threads are tied to CPU execution
The OS schedules threads onto logical CPUs.
At one instant:
So if you have 4 logical CPUs, roughly 4 OS threads can actually execute instructions simultaneously.
7. Physical core vs logical CPU
Without SMT / Hyper-Threading:
With SMT / Hyper-Threading:
So a machine might say:
The OS generally schedules against those 16 logical CPUs.
Full Go picture
Putting everything together:
The two schedulers are important:
8. What happens when a goroutine launches OpenSSL
This is different because OpenSSL becomes a separate process.
Suppose you write:
Conceptually:
The OpenSSL process has its own address space and own OS thread(s).
So:
The OpenSSL process is not an OS thread itself.
9. Your certificate service example
Say you have:
You could conceptually have:
All of those threads compete for the same CPU resources.
That's why creating:
does not mean you get 1000-way CPU parallelism.
If you only have 8 logical CPUs:
Only a limited amount can actually execute at once.
The shortest version to remember
And for Go, insert one extra layer:
And for your OpenSSL case:
That entire model is the foundation for understanding why goroutine count, GOMAXPROCS, CPU cores, semaphores, and spawning many OpenSSL processes affect the performance of your certificate service.