posts - 200, comments - 8, trackbacks - 0, articles - 0

进程/线程 同步机制

Posted on 2012-12-14 11:46 鑫龙 阅读(472) 评论(0)  编辑 收藏 引用 所属分类: linux编程

1 什么时候需要同步?

2 在linux中, 线程同步机制有哪些?各适用在怎样的条件?进程同步有哪些?对应的数据类型、API 各有哪些?
在当前的POSIX标准中有三种线程同步机制,它们分别是:互斥量、读写锁、条件变量。
关于进程同步机制,POSIX定义了一种信号灯,而system V 定义了另外一种信号灯。
---------------------------------------------------------------------- 
线程同步

(1)、互斥量(mutex)

  互斥量本质上是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。

  对互斥量进行加锁以后,任何其它试图再次对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为运行状态的线程可以对互斥量加锁,其它线程将会看到互斥锁依然被锁住,只能回去再次等待它重新变为可用。在这种情况下,每次只有一个线程可以向前执行。

pthread_mutex_t 
pthread_mutex_init();
pthread_mutex_lock();
pthread_mutex_unlock();
pthread_mutex_destroy();
(2)、读写锁

  读写锁与互斥量类似,不过读写锁允许更高的并行性。互斥量要么是锁住状态要么是不加锁状态,而且一次只有一个线程可以对其加锁。

  读写锁可以由三种状态:读模式下加锁状态写模式下加锁状态不加锁状态。一次只有一个线程可以占有写模式的读写锁,但是多个线程可以同时占有读模式的读写锁。

  在读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞。当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是如果线程希望以写模式对此锁进行加锁,它必须阻塞直到所有的线程释放读锁。虽然读写锁的实现各不相同,但当读写锁处于读模式锁住状态时,如果有另外的线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁请求。这样可以避免读模式锁长期占用,而等待的写模式锁请求一直得不到满足。

  读写锁非常适合于对数据结构读的次数远大于写的情况。当读写锁在写模式下时,它所保护的数据结构就可以被安全地修改,因为当前只有一个线程可以在写模式下拥有这个锁。当读写锁在读状态下时,只要线程获取了读模式下的读写锁,该锁所保护的数据结构可以被多个获得读模式锁的线程读取。

  读写锁也叫做共享-独占锁,当读写锁以读模式锁住时,它是以共享模式锁住的;当他以写模式锁住时,它是以独占模式锁住的。

pthread_rwlock_t
pthread_rwlock_init();
pthread_rwlock_rdlock();
pthread_rwlock_wrlock();
pthread_rwlock_unlock();
pthread_rwlock_destroy();
(3) 、条件变量(condition)和监视器(monitor)

  条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定的条件发生。

  条件本身是由互斥量保护的。线程在改变条件状态前必须首先锁住互斥量,其它线程在获得互斥量之前不会察觉到这种改变,因此必须锁定互斥量以后才能计算条件。

pthread_cond_t
pthread_cond_init();
pthreadf_cond_wait();
pthread_cond_signal();
pthread_cond_destroy();
----------------------------------------------------------------------
进程同步 
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。

POSIX信号灯:
sem_t
sem_open();
sem_init();
sem_wait();
sem_post();
sem_close();
sem_unlink();
SysV信号灯:
semget();
semop();
semctl();
3 线程同步机制和进程同步机制有什么区别?哪个使用的范围更大?
显然进程同步机制可以用于线程同步,而线程同步机制不能用于进程同步。





只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理