Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7410
  • 博文数量: 13
  • 博客积分: 520
  • 博客等级: 中士
  • 技术积分: 140
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-15 15:29
文章分类
文章存档

2010年(13)

我的朋友
最近访客

分类: LINUX

2010-04-21 20:15:42

 1.互斥锁
  

在内核中可以使用互斥锁来实现信号量行为。内核互斥锁是在原子 API 之上实现的,但这对于内核用户是不可见的。互斥锁很简单,但是有一些规则必须牢记。同一时间只能有一个任务持有互斥锁,而且只有这个任务可以对互斥锁进行 解锁。互斥锁不能进行递归锁定或解锁,并且互斥锁可能不能用于交互上下文。但是互斥锁比当前的内核信号量选项更快,并且更加紧凑,因此如果它们满足您的需 求,那么它们将是您明智的选择。

可以通过 DEFINE_MUTEX 宏使用一个操作创建和初始化互斥锁。这将创建一个新的互斥锁并初始化其结构。可以在 ./linux/include/linux/mutex.h 中查看该实现。

                DEFINE_MUTEX( my_mutex );

互斥锁 API 提供了 5 个函数:其中 3 个用于锁定,一个用于解锁,另一个用于测试互斥锁。首先看一下锁定函数。在需要立即锁定以及希望在互斥锁不可用时掌握控制的情形下,可以使用第一个函数 mutex_trylock

pthread_mutex_init

pthread_mutex_lock

pthread_mutex_trylock
pthread_mutex_unlock
pthread_mutex_destroy


ret = mutex_trylock( &my_mutex );
if (ret != 0) {
// Got the lock!
} else {
// Did not get the lock
}


                
mutex_lock( &my_mutex );

// Lock is now held by the caller.

if (mutex_lock_interruptible( &my_mutex ) != 0) {

// Interrupted by a signal, no mutex held

}

当一个互斥锁被锁定后,它必须被解锁。这是由 mutex_unlock 函数来完成的。这个函数不能从中断上下文调用。最后,可以通过调用 mutex_is_locked 检查互斥锁的状态。这个调用实际上编译成一个内联函数。如果互斥锁被持有(锁定),那么就会返回 1;否则,返回 0。清单 12 演示了这些函数。



                
mutex_unlock( &my_mutex );

if (mutex_is_locked( &my_mutex ) == 0) {

// Mutex is unlocked

}

互斥锁 API 存在着自身的局限性,因为它是基于原子 API 的。但是其效率比较高,如果能满足你的需要,还是可以使用的。

在 Linux 中,pthread 库调用 pthread_mutex_lock()pthread_mutex_trylock() 都可以用来获取互斥锁:

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);


Linux 使用 pthread_mutex_unlock() 来释放互斥锁:

int pthread_mutex_unlock(pthread_mutex_t *mutex);


在 Linux 中, pthread_mutex_destroy() 用来销毁一个互斥对象,并释放它持有的所有资源。这个调用还会检查当时这个互斥锁是否已经被释放了:

int pthread_mutex_destroy(pthread_mutex_t *mutex);



2.信号量


在 Linux 中,系统调用 sem_init() 用来创建一个 POSIX 信号量:

int sem_init(sem_t *sem, int pshared, unsigned int value);

其中 value (信号量的计数)被设置为该信号量的初值。

Linux pthreads 使用 pthread_cond_init() 来创建一个条件变量:

int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

pthread_cond_t 类型的条件变量可以使用常量 PTHREAD_COND_INITIALIZER 静态地进行初始化;还可以使用 pthread_condattr_init() 进行初始化,后者会对与这个条件变量有关的属性进行初始化。系统调用 pthread_condattr_destroy() 用来销毁属性:


Linux POSIX 信号量使用 sem_wait() 挂起调用线程,直到这个信号量的计数为非 0;然后自动减少这个信号量的计数:

int sem_wait(sem_t * sem)

在 POSIX 信号量中,没有超时功能。这可以在一个循环中执行非阻塞的 sem_trywait() 来实现,该循环可以计数超时值:

int sem_trywait(sem_t * sem);

Linux pthreads 使用 pthread_cond_wait() 来不确定地阻塞调用线程:

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);


Linux POSIX 信号量使用 sem_post() 来释放事件信号量,这样可以唤醒一个正在因该信号量而阻塞的线程:

int sem_post(sem_t * sem);

pthread_cond_signal() 调用用来在 LinuxThreads 中唤醒正在等待这个条件变量的一个线程,而 pthread_cond_broadcast() 调用则用来唤醒正在等待这个条件变量的所有线程。

int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);

注意,条件函数不是异步信号安全的,不应该在信号处理函数中调用。在特殊情况下,如果在信号处理函数中调用 pthread_cond_signalpthread_cond_broadcast ,可能会导致调用线程的死锁。



Linux POSIX 信号量使用 sem_destroy() 来销毁信号量:

int sem_destroy(sem_t * sem);

在 Linux pthreads 中, pthread_cond_destroy() 用来销毁条件变量:

int pthread_cond_destroy(pthread_cond_t *cond);





    HEV hevIpcInterrupt;
unsigned long ulPostCnt = 0;
unsigned long ulrc; // return code
unsigned long ulTimeout = 10 ; // timeout value
/* create event semaphore */
DosCreateEventSem (NULL, &hevIpcInterrupt, 0, TRUE);
/* In Thread A */
/* Wait forever for event to be posted */
DosWaitEventSem (hevIpcInterrupt, (unsigned long)
SEM_INDEFINITE_WAIT);
/* immediately unblocked as the semaphore is already posted */
/* Waits until the semaphore is posted */
DosWaitEventSem (hevIpcInterrupt, (unsigned long)
SEM_INDEFINITE_WAIT);
/* In Thread B */
DosPostEventSem(hevIpcInterrupt);
/* Close the semaphore */
ulrc = DosCloseEventSem (hevIpcInterrupt);

  
阅读(225) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~