PLCs still execute one instruction at a time, just like in other languages. They appear parallel from an I/O standpoint (your description of PLC's I/O scan is accurate).
But PROGRAM and TASK code blocks are run in sequence, but not all codeblocks run every scan. The System Tasks run at various times.
$tFirstScan runs on first scan
$tLastScan runs when PLC transitions from RUN->PROGRAM mode (NOT power-down)
These system tasks will run on the PLC scan after $tFirstScan finishes.
$tTopOfScan runs before all other PROGRAM and TASK code-blocks
$Main
$tBottomOfScan runs after all other PROGRAM and TASK code-blocks
Any other User PROGRAMs or TASKs are run somewhere between $tTopOfScan and $tBottomOfScan, similar to $Main. You can tweak the order of execution within a scan for $Main and User PROGRAMs and TASKs from the Project Browser. Make sure you are in Edit Mode (Ctrl+E), then right-click on a code-block in the Project Browser and select "Change Execution Order" to bring up that dialog.
We have some Power Point training slides available on our website (
www.hosteng.com) and look in the left frame for Training Slides/All Do-more PLCs. Look at presentation #7, Programs vs. Tasks. That goes into much more detail.