线程/进程的同步
同一进程中的不同线程间共享进程的全局变量、文件描述符。
线程或进程的同步方式:信号量和互斥量
临界区
线程/进程可以访问共享资源,但是有些资源同一时间只能一个线程访问,这种资源称为临界资源,如打印机等。此外,还有许多变量、数据等都可以被若干进程共享,也属于临界资源。访问临界资源必须互斥的进行,访问临界资源的代码称为临界区。
正确的访问临界资源的步骤如下:
1、进入临界区。为了访问临界资源,进入临界区时必须检查临界资源是否可以访问,如果可以,那么设立访问标识符(比如上锁),以便独占。
2、临界区。进程/线程对临界资源的访问、操作的一系列代码。
3、退出临界区。退出时必须清除正在访问临界资源的标识符(比如解锁)。
4、剩余区。代码中的剩余部分。
信号量
生产者:
1 for(;;) { 2 sem_wait(&put); 3 write_to_buffer(); 4 sem_post(&get); 5 }
消费者:
1 for(;;) { 2 sem_wait(&get); 3 read_from_buffer(); 4 sem_post(&put); 5 }
上面生产者和消费者的代码是典型的信号量使用情景。生产者可以只对某个信号量wait操作(P操作),而不做post操作(V操作),这是和互斥锁不一样的地方。
信号量分为有名信号量(named)和基于内存的信号量(memory-based)。 有名信号量是在内核创建一个文件,内容是0或者1,图如下:
无名信号量是在内存空间开辟一片共享内存,给多个进程或者线程共享。
同一进程间的不同线程示意图如下:
不同进程间如下:用函数sem_open()创建,sem_close()和sem_unlink()关闭和删除这个named semaphore。
互斥量
信号量和互斥量区别
信号量和互斥锁都可以用于线程和进程间的同步。而信号量+条件变量是作为同一线程间的同步机制,这些线程总是共享某个内存区的。
互斥锁是信号量为二元值(0/1)的一种特例,当信号量量为0时相当于上锁。
条件变量
互斥锁用来上锁,条件变量则用于等待。
死锁
什么是死锁?如何防止死锁?
天行健,君子当自强不息