27.6 IPv6 Routing Header


26.9 Web Client and Simultaneous Connections (Continued)

We now recode our Web client from Section 26.6, removing the call to the Solaris thr_join function and replacing it with a call to pthread_join . As discussed in that section, we now must specify exactly which thread we are waiting for. To do this we will use a condition variable, as described in Section 26.8

The only change to the globals (Figure 26.13) is to add one new flag and the condition variable.

 
 #define F_JOINED 8 /* main has pthread_join'ed */ int ndone; /* number of terminated threads */ pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER; 

The only change to the do_get_read function (Figure 26.15) is to increment ndone and signal the main loop before the thread terminates.

 
 printf("end-of-file on %s\n", fptr->f_name); Close(fd); Pthread_mutex_lock(&ndone_mutex); fptr->f_flags = F_DONE; /* clears F_READING */ ndone++; Pthread_cond_signal(&ndone_cond); Pthread_mutex_unlock(&ndone_mutex); return(fptr); /* terminate thread */ } 

Most changes are in the main loop, Figure 26.14, the new version of which we show in Figure 26.19.

Figure 26.19 Main processing loop of main function.

threads/web03.c

 43 while (nlefttoread > 0) { 44 while (nconn < maxnconn && nlefttoconn > 0) { 45 /* find a file to read */ 46 for (i = 0; i < nfiles; i++) 47 if (file[i].f_flags == 0) 48 break; 49 if (i == nfiles) 50 err_quit("nlefttoconn = %d but nothing found", nlefttoconn); 51 file[i].f_flags = F_CONNECTING; 52 Pthread_create(&tid, NULL, &do_get_read, &file[i]); 53 file[i].f_tid = tid; 54 nconn++; 55 nlefttoconn--; 56 } 57 /* Wait for thread to terminate */ 58 Pthread_mutex_lock(&ndone_mutex); 59 while (ndone == 0) 60 Pthread_cond_wait(&ndone_cond, &ndone_mutex); 61 for (i = 0; i < nfiles; i++) { 62 if (file[i].f_flags & F_DONE) { 63 Pthread_join(file[i].f_tid, (void **) &fptr); 64 if (&file[i] != fptr) 65 err_quit("file[i]!= fptr"); 66 fptr->f_flags = F_JOINED; /* clears F_DONE */ 67 ndone--; 68 nconn--; 69 nlefttoread--; 70 printf("thread %d for %s done\n", fptr->f_tid, fptr->f_name); 71 } 72 } 73 Pthread_mutex_unlock(&ndone_mutex); 74 } 75 exit(0); 76 } 

If possible, create another thread

44 “56 This code has not changed.

Wait for thread to terminate

57 “60 To wait for one of the threads to terminate, we wait for ndone to be nonzero. As discussed in Section 26.8, the test must be done while the mutex is locked. The sleep is performed by pthread_cond_wait .

Handle terminated thread

61 “73 When a thread has terminated, we go through all the file structures to find the appropriate thread, call pthread_join , and then set the new F_JOINED flag.

Figure 16.20 shows the timing for this version, along with the timing of the version using nonblocking connect s.



UNIX Network Programming Volume 1, Third Edition
Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition)
ISBN: 0131411551
EAN: 2147483647
Year: 2003
Pages: 441

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net