You have two synchronization problems here.
Let's deal with the easier one first, the fact that you're sharing a global buff_list that the two threads fight over. There's nothing stopping one thread from trying to append at the same time the other thread pops, which is illegal. And, even if you get lucky and that doesn't happen, the pop could come before the append.
The simplest way to solve this is to use a Queue, which is automatically-synchronizing:
buff_list = Queue.Queue()
Then just use put instead of append, and get instead of pop.
However, if you want to learn how to this stuff yourself, there are two possible ways to go.
First, you can use a Lock. (You can also use an RLock, but let's forget that for now.) This makes sure that only one thread is accessing buff_list at a time.
buff_lock = threading.Lock()
buff_list = []
Now, whenever you append or pop, just grab the lock:
with buff_lock:
buff_list.append("C")
with buff_lock:
val = buff_list.pop()
But this won't make sure the popping code waits until there's something to pop. If you want to do that, use a Condition:
buff_cond = threading.Condition()
Now:
with buff_cond:
buff_list.append("C")
buff_cond.notify()
with buff_cond:
while not buff_list:
buff_cond.wait()
value = buff_list.pop()
The second problem is that you're implicitly sharing sys.stdin, because both threads are calling raw_input. Unless you have some way to synchronize things so that each thread knows when it's supposed to get the next input (and that may be hard to even describe, and you can't turn it into code if you can't describe it), that can't possibly work—every time you type C there's a 50/50 chance that the wrong thread will get it.
So, as kirelagin suggests, you need to make exactly one thread responsible for the I/O. The easiest way to do this is again to use a Queue, and have one thread put any inputs it doesn't use, and the other thread can get from the queue.
whileandifconditions, and shouldn't use them. Also, you never need to checklen(buff_list) > 0; just checkbuff_list, because any sequence is truthy iff it's not empty. The problem with adding unnecessary parentheses,lenchecks, etc. is that most Python programmers will assume you were trying to do something for which they are necessary, and waste time and mental effort trying to guess what your intention was.list.pop()and not store the result anywhere. But I assume you know that, and were just doing it this way because it's a toy example (the value can't be anything but"C", and you have nothing useful to do with it anyway).