Make Libraries Safe and Hot
The most important design issue is simplicity!
由于多线程程序难以调试,现有的调试工具也不好用,所以设计一定要强调简单。
Make malloc() More Concurrent
Manipulate Lists
Single, Global Mutex
多线程程序设计的最高策略
1. Master/Slave: 1个线程做主要的事情,并创建其他的线程。最普通最简单的形式。
2. Client/Server(Thread per Request):1个线程监听请求,并为每个请求创建个线程来处理。
3. Client/Server(Thread per Client):1个线程监听客户端的连接,并为每个客户端创建1个连接。
4. Producer/Consumer(Work Queue or Workpile):一些线程创建工作请求并放入queue;另外一些线程从queue中提取工作请求并处理。
5. Dogpile:所有的线程直接寻找工作。
6. Pipeline:每个线程会处理按照任务处理一部分工作,然后把部分完成的工作移交给下一线程。
Client/Server(Thread per Request)模式的socket设计
while(TRUE)
{
newsockfd = accept(sockfd, &cli_addr, &client);
PTHREAD_CREATE(&tid, &thr_attr, process_request, newsockfd);
}
void * process_request(void *arg)
{
...
read(mysocfd, date, LENGTH);
result = process_data(data);
write(mysocfd, result, LENGTH);
close(mysocfd);
pthread_exit();
}
简单,直接。缺点是当请求数很大时,会导致较大的线程创建开销。
Client/Server(Thread per Client)模式的socket设计
while(TRUE)
{
newsockfd = accept(sockfd, &cli_addr, &clilent);
PTHREAD_CREATE(&tid, &thr_attr, process_requests, newsockfd);
}
void * process_requests()
{
...
while(TRUE){
read(mysocfd, data, LENGTH);
if (done(data))
break;
result = process_data(data);
write(mysocfd, result, LENGTH);
}
}
线程创建开销会有限,线程可以维护状态。这种模式对数据库编写者比较有吸引力。
Producer/Consumer模式的socket设计
for(i=0;i PTHREAD_CREATE(&tid, &thr_attr, process_request, NULL);
}
...
while(TRUE)
{
newsockfd = accept(sockfd, &cli_addr &clinlen);
add_to_queue(newsockfd);
}
void * process_request(void *arg)
{
while(TRUE){
read(mysocfd, date, LENGTH);
result =process_data(data);
write(mysocfd, result, LENGTH);
close(mysocfd);
}
}
Dogpile模式的socket设计
for(i=0; i PTHREAD_CREATE(&tid, &thr_attr, process_request, newsockfd);
}
void* process_request()
{
...
while(TRUE){
pthread_mutex_lock(&m);
newsockfd = accept(sockfd, &cli_addr, &client);
pthread_mutex_unlock(&m);
read(mysocfd, data, LENGTH);
reslut=process_data(data);
write(mysocfd, result, LENGTH);
close(mysocfd);
}
}
Pipline模式的socket设计
PTHREAD_CREATE(&tid, &thr_attr, process_request_1, newsockfd);
PTHREAD_CREATE(&tid, &thr_attr, process_request_2, newsockfd);
void *process_request_1()
{
...
while(TRUE){
newsockfd = accept(sockfd, &cli_addr, &clilen);
read(mysocfd, data, LENGTH);
reslut_1 = process_data_1(data);
add_queue_2(result_1);
}
}
void *process_request_2()
{
...
while(TRUE){
result_1 = get_from_queu_1();
result_2 = process_data_2(result_1);
write(mysocfd, result_2, LENGTH);
close(mysocfd);
}
}
总结:没有万能的锁机制。要根据情况合理选择。这是一个开放性的问题。
阅读(675) | 评论(0) | 转发(0) |