A memory lock is associated with a virtual page, not a real frame. The paging rule is: If a frame backs at least one locked page, don’t page it out.
Memory locks do not stack. I.e., you can’t lock a particular page twice so that it has to be unlocked twice before it is truly unlocked. It is either locked or it isn’t.
A memory lock persists until the process that owns the memory explicitly unlocks it. (But process termination and exec cause the virtual memory to cease to exist, which you might say means it isn’t locked any more).
Memory locks are not inherited by child processes. (But note that on a modern Unix system, immediately after a fork, the parent’s and the child’s virtual address space are backed by the same real page frames, so the child enjoys the parent’s locks). See Creating a Process.
Because of its ability to impact other processes, only the superuser can lock a page. Any process can unlock its own page.
The system sets limits on the amount of memory a process can have locked and the amount of real memory it can have dedicated to it. See Limits on Resources.
In Linux, locked pages aren’t as locked as you might think. Two virtual pages that are not shared memory can nonetheless be backed by the same real frame. The kernel does this in the name of efficiency when it knows both virtual pages contain identical data, and does it even if one or both of the virtual pages are locked.
But when a process modifies one of those pages, the kernel must get it a separate frame and fill it with the page’s data. This is known as a copy-on-write page fault. It takes a small amount of time and in a pathological case, getting that frame may require I/O.
To make sure this doesn’t happen to your program, don’t just lock the pages. Write to them as well, unless you know you won’t write to them ever. And to make sure you have pre-allocated frames for your stack, enter a scope that declares a C automatic variable larger than the maximum stack size you will need, set it to something, then return from its scope.