It doesn't as much "get" CPU, as it just runs on it. The kernel decides on which core and when and for how long the process runs. It schedules the tasks so that each process gets its time slices on the CPU: it runs for a while, then either after the time slice expires, or a system call occurs, the context is switched to another process. The state of the program is stored before the switch and restored when the kernel decides it deserve another slice of time, so that it doesn't even notice the time gap. The scheduling may vary - it may have a fixed timer (milliseconds usually), or it may be tickless... the kernel also manages the scheduling according to the priority of the process (
nice). The process may be locked onto specific cores (
taskset). For a multithreaded program, threads get their slices independently and may run concurrently. The kernel can suspend the program completely and resume it at a later time (triggered by SIGSTOP and SIGCONT).
The memory is virtualized. The pointers that you see in your programming languages are not physical blocks of memory, but virtual addresses remapped to the physical layer. The kernel serves RAM in pages (for instance, 4kB), and even shuffles them around a bit (a page may be swapped to the hard disk and only restored in RAM when you access it).
mmap is one way to map a new page to some address (where the pages may refer to a file from the hard drive, mapped to the memory). However, when you dynamically allocate memory (
malloc and other allocators), it is up to the allocator what to do. It usually calls
sbrk syscall to request more space for its memory pool, or
mmap for larger chunks - implementations may vary.
So, to sum up: the process priority and CPU affinities may be set, but the scheduler takes care of how and when the program runs, no need to interact with the kernel in any way. Memory is served in pages and requested through system calls. Once you allocated the memory, you access it without intervention of the kernel, simply through the virtual address space.