Thread alternatives for embedded systems
Threading is a higher level concept than microcontroller programming. Simply put, threads are implemented as a scheduler that uses timer interrupts, which in turn saves the program counter + stack pointer etc and sets those to different locations. So it is quite possible and easy to implement a similar concept using interrupts - with the benefit that you get specialized interrupts instead of generic multi-threading.
That's about the only sensible way to do it with a restricted legacy 8 bitter like PIC, which is extremely limited when it comes to stack use. Forget about using thread libs, even those written for microcontrollers. That will only add excessive bloat and complexity, for nothing gained. It is a bad idea in general to drag PC programming concepts into the embedded world.
What you should be doing, is to put your button scanning inside a cyclic timer interrupt that's executed once per 10ms or so. From inside the interrupt, you poll the buttons and compare the button read with the previous once, for debouncing purposes. The result of this is stored in a variable shared with the main program, declared as volatile
and protected from race conditions. Since you only write to the variable from inside the interrupts, it may be sufficient protection to ensure that reads are 8 bits, but you must disassemble to be sure. More info about that here: Using volatile in embedded C development.
Use interrupts
You want to run some code when pressing a button? Use a pin-change-interrupt
You want to do something at a fixed interval? Use a timer-interrupt
In a way, the hardware of the microcontroller runs a 'thread' that monitors the interrupt sources, and runs a 'callback' or interrupt-routine for each event.
The main program is automatically paused while executing the interrupt.
A common way to share data between interrupts and main code is through volatile
global variables and temporarily disable interrupts when reading data from these globals when they are more than the word-size of the controller (almost always on an 8 bit controller)
I would probably suggest a cooperative multitasking library. One that I have used in the past is Protothreads: http://www.dunkels.com/adam/pt/
Any decent cooperative multitasking library will help abstract away the implicit state machine required to keep track of things.
Good luck.