Each process has its own virtual space and resources. To create two tasks running in parallel, you had to create two processes. Today, most operating systems provide some level of threading. By using threads, you can create two tasks that run within the same process. These threads share a common virtual address space, but have separate stacks and control registers.
Threads also share open files.
Threads make it easier for you to share data between the two tasks. But because the two tasks share resources, threads must be ready to synchronize access to shared resources. The two synchronization primitives are locks and condition variables. Locks Locks provide mutual exclusion. Most lock interfaces provide an initialization function, a lock function, and an unlock function.