0
点赞
收藏
分享

微信扫一扫

一起来写web server 04 -- 线程池版本

IT程序员 2021-09-27 阅读 58

从这个版本开始,后面的代码差不多是越来越难啦.

这个版本,我们主要是要实现一个线程池版本的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,
}
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( /* 销毁锁 */
}

MutexLock这个类巧妙的利用了CPP类的特性来管理锁这个资源.
接下来比较重要的是加锁以及解锁操作:

void lock()
{
MCHECK(pthread_mutex_lock(
assignHolder(); /* 指定拥有者 */
}

void unlock()
{
unassignHolder(); /* 丢弃拥有者 */
MCHECK(pthread_mutex_unlock(
}

如何来使用这个锁呢?muduo库设计了另外一个类,叫做MutexLockGuard.这个类非常简单:

class MutexLockGuard : noncopyable
{
public:
explicit MutexLockGuard(MutexLock& mutex)
: mutex_(mutex)
{

mutex_.lock(); /* 构造时加锁 */
}
~MutexLockGuard()
{
mutex_.unlock(); /* 析构时解锁 */
}
private:
MutexLock /* 持有锁的一个引用 */
};

通过这个类,我们就可以很方便的实现加锁和解锁操作了,我们只需要向之前代码里那样使用就行了:

{
MutexLockGuard lock(mutex); /* 加锁 */
...do other thing...
}

在这个中括号包围的作用域里,锁是有效的,出了这个作用域,lock析构了,锁就解开了,代码很漂亮.

总结

好了,这个版本的代码就是这样啦,感兴趣的同学可以到这里来查看代码:
https://github.com/lishuhuakai/Spweb

举报

相关推荐

0 条评论