UNIX Network Programming Volume 1, Third Edition [Electronic resources] : The Sockets Networking API نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

UNIX Network Programming Volume 1, Third Edition [Electronic resources] : The Sockets Networking API - نسخه متنی

Addison Wesley

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید










30.10 TCP Concurrent Server, One Thread per Client


The last five sections have focused on one process per client, both one fork per client and preforking some number of children. If the server supports threads, we can use threads instead of child processes.

Our first threaded version is shown in Figure 30.4 that creates one thread per client, instead of one process per client. This version is very similar to Figure 26.3.


Main thread loop


1923 The main thread blocks in a call to accept and each time a client connection is returned, a new thread is created by pthread_create. The function executed by the new thread is doit and its argument is the connected socket.


Per-thread function


2533 The doit function detaches itself so the main thread does not have to wait for it and calls our web_client function (Figure 30.3). When that function returns, the connected socket is closed.

Figure 30.26 main function for TCP threaded server.

server/serv06.c


1 #include "unpthread.h"
2 int
3 main(int argc, char **argv)
4 {
5 int listenfd, connfd;
6 void sig_int(int);
7 void *doit(void *);
8 pthread_t tid;
9 socklen_t clilen, addrlen;
10 struct sockaddr *cliaddr;
11 if (argc == 2)
12 listenfd = Tcp_listen(NULL, argv[1], &addrlen);
13 else if (argc == 3)
14 listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
15 else
16 err_quit("usage: serv06 [ <host> ] <port#>");
17 cliaddr = Malloc(addrlen);
18 Signal(SIGINT, sig_int);
19 for ( ; ; ) {
20 clilen = addrlen;
21 connfd = Accept(listenfd, cliaddr, &clilen);
22 Pthread_create(&tid, NULL, &doit, (void *) connfd);
23 }
24 }
25 void *
26 doit(void *arg)
27 {
28 void web_child(int);
29 Pthread_detach(pthread_self());
30 web_child((int) arg);
31 Close((int) arg);
32 return (NULL);
33 }

We note from Figure 30.1 that this simple threaded version is faster than even the fastest of the preforked versions. This one-thread-per-client version is also many times faster than the one-child-per-client version (row 1).

In Section 26.5 we noted three alternatives for converting a function that is not thread-safe into one that is thread-safe. Our web_child function calls our readline function, and the version shown in Figure 3.18 is not thread-safe. Alternatives 2 and 3 from Section 26.5 were timed with the example in Figure 3.17 for the threaded server examples in this chapter.



/ 450