@lishuhuakai
2016-11-03T16:35:23.000000Z
字数 1877
阅读 1761
从这个版本开始,后面的代码差不多是越来越难啦.
这个版本,我们主要是要实现一个线程池版本的web server.这个版本的设计出自UNP.
思想非常简单,那就是父线程首先构建n多子线程,这些子线程全部争抢全局的一把锁,只有抢到了锁的线程才能够调用accept函数,否则都会阻塞掉.
/*-* 线程池版本的web server.主要的思想是事先构建一个线程池,只是需要注意的是,accept的时候需要加锁.*/int listenfd; /* 全局的一个监听套接字 */MutexLock mutex; /* 全局的一把锁 */int main(int argc, char *argv[]){listenfd = Open_listenfd(8080); /* 8080号端口监听 *///signal(SIGPIPE, SIG_IGN);pthread_t tids[10];void* thread_main(void *);for (int i = 0; i < 10; ++i) {int *arg = (int *)Malloc(sizeof(int)); /* 这个东西不会共享 */*arg = i;Pthread_create(&tids[i], NULL, thread_main, (void *)arg);}for ( ; ; )pause();return 0;}void* thread_main(void *arg){printf("thread %d starting\n", *(int*)arg);Free(arg);struct sockaddr cliaddr;socklen_t clilen;int connfd;while (true) {{MutexLockGuard lock(mutex); /* 加锁 */connfd = Accept(listenfd, &cliaddr, &clilen);}doit(connfd); /* 处理连接 */close(connfd); /* 关闭连接 */}}
一般涉及到多线程的资源共享,锁或者说互斥,加上一个同步机制,总是逃不开的话题.
对于共享资源的写,总是要加锁的.如何来构造一把锁呢?我这里的代码参考了muduo库的设计.
我们一起来看一下MutexLock这个类.
class MutexLock : noncopyable{private:pthread_mutex_t mutex_; /* 这是系统定义的锁的类型 */pid_t holder_; /* 记录拥有线程的id */...}
它的构造函数,仅仅是调用普通的锁的初始化的代码:
MutexLock(): holder_(0){pthread_mutex_init(&mutex_, NULL); /* 初始化 */}
它的析构函数,主要是调用锁的销毁函数.
~MutexLock(){assert(holder_ == 0);pthread_mutex_destroy(&mutex_); /* 销毁锁 */}
MutexLock这个类巧妙的利用了CPP类的特性来管理锁这个资源.
接下来比较重要的是加锁以及解锁操作:
void lock(){MCHECK(pthread_mutex_lock(&mutex_));assignHolder(); /* 指定拥有者 */}void unlock(){unassignHolder(); /* 丢弃拥有者 */MCHECK(pthread_mutex_unlock(&mutex_));}
如何来使用这个锁呢?muduo库设计了另外一个类,叫做MutexLockGuard.这个类非常简单:
class MutexLockGuard : noncopyable{public:explicit MutexLockGuard(MutexLock& mutex): mutex_(mutex){mutex_.lock(); /* 构造时加锁 */}~MutexLockGuard(){mutex_.unlock(); /* 析构时解锁 */}private:MutexLock& mutex_; /* 持有锁的一个引用 */};
通过这个类,我们就可以很方便的实现加锁和解锁操作了,我们只需要向之前代码里那样使用就行了:
{MutexLockGuard lock(mutex); /* 加锁 */...do other thing...}
在这个中括号包围的作用域里,锁是有效的,出了这个作用域,lock析构了,锁就解开了,代码很漂亮.
好了,这个版本的代码就是这样啦,感兴趣的同学可以到这里来查看代码:
https://github.com/lishuhuakai/Spweb