BIND的代码,有关锁的用法让我纠结了一个下午,困惑在于,一个线程已经LOCK了,为何其他的线程还是能够继续LOCK?
其中原因是在一个线程LOCK后,执行了WAIT处理,其内部是pthread_cond_wait的实现,通过man手册,有这段话非常重要
These functions atomically release mutex and cause the calling thread to block on the condition variable cond;
调用pthread_cond_wait后,自动释放mutex锁,并阻塞等待条件变量。
还有另外一个重要的话,当条件变量被触发后
Upon successful return, the mutex shall have been locked and shall be owned by the calling thread.
mutex锁将会LOCK,并成功返回。
先看下BIND中有关其task任务的处理,一个socket线程通过epoll机制接收到数据包,将其放在任务队列,通过线程条件变量激活worker线程处理,有一个全局lock锁来控制。
dispatch(isc__taskmgr_t *manager) {
...
LOCK(&manager->lock);
while (!FINISHED(manager)) {
...
WAIT(&manager->work_available, &manager->lock);
task = pop_readyq(manager);
if (task != NULL) {
UNLOCK(&manager->lock);
}
LOCK(&manager->lock);
}
}
之前就纠结在LOCK
处,主线程首先通过这个manager->lock来同步线程的创建。所有线程创建完毕后,主进程释放锁。
LOCK(&manager->lock);
/*
* Start workers.
*/
for (i = 0; i < workers; i++) {
if (isc_thread_create(run, manager,
&manager->threads[manager->workers])
== ISC_R_SUCCESS) {
...
manager->workers++;
started++;
}
}
UNLOCK(&manager->lock);
问题是如何想通的呢,通过对接口进行demo测试,找的使用的方法,以下就是当时demo的事例。
主进程创建多个线程,先通过mutex控制,线程创建完成后,再释放锁,线程通过pthread_cond_wait中阻塞,等待主进程随机唤醒。
当然这只是个demo,还有很多的问题要研究整理。
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static void *thread_func(void *arg)
{
printf("thread id : %ld set lock begin\n", pthread_self());
pthread_mutex_lock(&mtx);
printf("thread id : %ld set lock OK\n", pthread_self());
while (1) {
pthread_cond_wait(&cond, &mtx);
printf("thread id : %ld running\n", pthread_self());
pthread_mutex_unlock(&mtx);
pthread_mutex_lock(&mtx);
}
return 0;
}
int main(void)
{
pthread_t tid;
int i;
struct node *p;
pthread_mutex_lock(&mtx);
for (i=0; i<3; i++) {
pthread_create(&tid, NULL, thread_func, NULL);
}
sleep(5);
pthread_mutex_unlock(&mtx);
while(1){
printf("main loop signal\n");
pthread_cond_signal(&cond);
sleep(3);
}
return 0;
}