/* Create threads after we've done all the libevent setup. */
for (i = 0; i < nthreads; i++) {
//为线程池创建数目为nthreads的线程,worker_libevent为线程的回调函数,
create_worker(worker_libevent, &threads[i]);
}
/*
* Worker thread: main event loop
*/
static void *worker_libevent(void *arg) {
LIBEVENT_THREAD *me = arg;
/* Any per-thread setup can happen here; thread_init() will block until
* all threads have finished initializing.
*/
pthread_mutex_lock(&init_lock);
init_count++; //每创建新线程,将全局init_count加1
pthread_cond_signal(&init_cond); // 发送init_cond信号
pthread_mutex_unlock(&init_lock);
//新创建线程阻塞于此,等待事件
event_base_loop(me->base, 0); //Libevent的事件主循环
return NULL;
}
worker_libevent中给init_count加1的目的在thread_init函数的这段代码可以看出来,
1 /* Wait for all the threads to set themselves up before returning. */
2 pthread_mutex_lock(&init_lock);
3 while (init_count < nthreads) {
4 pthread_cond_wait(&init_cond, &init_lock);
5 }
6 pthread_mutex_unlock(&init_lock);
即主线程阻塞如此,等待worker_libevent发出的init_cond信号,唤醒后检查init_count < nthreads是否为假(即创建的线程数目是否达到要求),否则继续等待。
/*
* Set up a thread's information.
*/
static void setup_thread(LIBEVENT_THREAD *me) {
me->base = event_init();
if (! me->base) {
fprintf(stderr, "Can't allocate event base\n");
exit(1);
}
/* Listen for notifications from other threads */
//为管道设置读事件监听,thread_libevent_process为回调函数
event_set(&me->notify_event, me->notify_receive_fd,
EV_READ | EV_PERSIST, thread_libevent_process, me);
event_base_set(me->base, &me->notify_event);
if (event_add(&me->notify_event, 0) == -1) {
fprintf(stderr, "Can't monitor libevent notify pipe\n");
exit(1);
}
//为新线程创建连接CQ链表
me->new_conn_queue = malloc(sizeof(struct conn_queue));
if (me->new_conn_queue == NULL) {
perror("Failed to allocate memory for connection queue");
exit(EXIT_FAILURE);
}
//初始化线程控制器内的CQ链表
cq_init(me->new_conn_queue);
if (pthread_mutex_init(&me->stats.mutex, NULL) != 0) {
perror("Failed to initialize mutex");
exit(EXIT_FAILURE);
}
//创建cache
me->suffix_cache = cache_create("suffix", SUFFIX_SIZE, sizeof(char*),
NULL, NULL);
if (me->suffix_cache == NULL) {
fprintf(stderr, "Failed to create suffix cache\n");
exit(EXIT_FAILURE);
}
}