Π Π»ΠΈΡΡΠΈΠ½Π³Π΅ 30.15 ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠ½ΠΊΡΠΈΠΈ my_lock_wait ΠΈ my_lock_release. ΠΠ½ΠΈ ΡΠΎΠ΄Π΅ΡΠΆΠ°Ρ Π²ΡΠ·ΠΎΠ²Ρ ΡΡΠ½ΠΊΡΠΈΠΉ Pthreads, ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½Π½ΡΡ Π΄Π»Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ ΡΠ°Π·Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ.
ΠΠΈΡΡΠΈΠ½Π³ 30.15. Π€ΡΠ½ΠΊΡΠΈΠΈ my_lock_wait ΠΈ my_lock_release: ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΎΠΊ Pthread
//server/lock_pthread.c
17 void
18 my_lock_wait()
19 {
20 Pthread_mutex_lock(mptr),
21 }
22 void
23 my_lock_release()
24 {
25 Pthread_mutex_unlock(mptr);
26 }
Π‘ΡΠ°Π²Π½ΠΈΠ²Π°Ρ ΡΡΡΠΎΠΊΠΈ 3 ΠΈ 4 ΡΠ°Π±Π». 30.1, ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ Π²Π΅ΡΡΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠ°Ρ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ, Ρ Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΠ·ΡΠ΅ΡΡΡ Π±ΠΎΠ»Π΅Π΅ Π²ΡΡΠΎΠΊΠΈΠΌ Π±ΡΡΡΡΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ΠΌ, ΡΠ΅ΠΌ Π²Π΅ΡΡΠΈΡ Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΎΠΉ ΡΠ°ΠΉΠ»Π°.
30.9. Π‘Π΅ΡΠ²Π΅Ρ TCP Ρ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΠΌ ΠΏΠΎΡΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ²: ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ° Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠ°
ΠΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΈΠ΅ΠΉ Π½Π°ΡΠ΅Π³ΠΎ ΡΠ΅ΡΠ²Π΅ΡΠ° Ρ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΠΌ ΠΏΠΎΡΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² ΡΠ²Π»ΡΠ΅ΡΡΡ Π²Π΅ΡΡΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ accept, Π° Π·Π°ΡΠ΅ΠΌ Β«ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΒ» ΠΏΡΠΈΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½Π½ΡΠΉ ΡΠΎΠΊΠ΅Ρ ΠΊΠ°ΠΊΠΎΠΌΡ-Π»ΠΈΠ±ΠΎ ΠΎΠ΄Π½ΠΎΠΌΡ Π΄ΠΎΡΠ΅ΡΠ½Π΅ΠΌΡ ΠΏΡΠΎΡΠ΅ΡΡΡ. ΠΡΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ ΠΎΠ±ΠΎΠΉΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡ Π·Π°ΡΠΈΡΡ Π²ΡΠ·ΠΎΠ²Π° accept, Π½ΠΎ ΡΡΠ΅Π±ΡΠ΅Ρ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΡΠΏΠΎΡΠΎΠ±Π° ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠ° ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΌ ΠΈ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠ°ΠΌΠΈ. ΠΡΠ° ΡΠ΅Ρ Π½ΠΈΠΊΠ° ΡΠ°ΠΊΠΆΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΡΠ»ΠΎΠΆΠ½ΡΠ΅Ρ ΠΊΠΎΠ΄, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΎΠΌΡ ΠΏΡΠΎΡΠ΅ΡΡΡ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡΡΡ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΈΠ· Π΄ΠΎΡΠ΅ΡΠ½ΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² Π·Π°Π½ΡΡΡ, Π° ΠΊΠ°ΠΊΠΈΠ΅ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½Ρ, ΡΡΠΎΠ±Ρ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΡΠΌ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠ°ΠΌ.
Π ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΡ ΠΏΡΠΈΠΌΠ΅ΡΠ°Ρ ΡΠ΅ΡΠ²Π΅ΡΠ° Ρ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΠΌ ΠΏΠΎΡΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΎΠΌΡ ΠΏΡΠΎΡΠ΅ΡΡΡ Π½Π΅ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΠ»ΠΎΡΡ Π±Π΅ΡΠΏΠΎΠΊΠΎΠΈΡΡΡΡ ΠΎ ΡΠΎΠΌ, ΠΊΠ°ΠΊΠΎΠΉ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠΌ. ΠΡΠΈΠΌ Π·Π°Π½ΠΈΠΌΠ°Π»Π°ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ°, ΠΎΡΠ³Π°Π½ΠΈΠ·ΡΡ Π²ΡΠ·ΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΈ accept ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΡΡ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² ΠΈΠ»ΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ ΡΠ°ΠΉΠ»Π° ΠΈΠ»ΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ. ΠΠ· ΠΏΠ΅ΡΠ²ΡΡ Π΄Π²ΡΡ ΡΡΠΎΠ»Π±ΡΠΎΠ² ΡΠ°Π±Π». 30.2 Π²ΠΈΠ΄Π½ΠΎ, ΡΡΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ°, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΡ ΠΏΡΠΎΠ²ΠΎΠ΄ΠΈΠΌ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ, ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅Ρ ΡΠ°Π²Π½ΠΎΠΌΠ΅ΡΠ½ΡΡ ΡΠΈΠΊΠ»ΠΈΡΠ΅ΡΠΊΡΡ Π·Π°Π³ΡΡΠ·ΠΊΡ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈΠΌΠΈ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡΠΌΠΈ.
Π Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π΄ΠΎΡΠ΅ΡΠ½Π΅Π³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ° Π½Π°ΠΌ Π½ΡΠΆΠ½Π° Π½Π΅ΠΊΠ°Ρ ΡΡΡΡΠΊΡΡΡΠ°, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠ°Ρ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ Π½Π΅ΠΌ. ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΎΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» child.h, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΡΡΡ ΡΡΡΡΠΊΡΡΡΠ° Child, ΠΏΠΎΠΊΠ°Π·Π°Π½ Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 30.16.
ΠΠΈΡΡΠΈΠ½Π³ 30.16. Π‘ΡΡΡΠΊΡΡΡΠ° Child
//server/child.h
1 typedef struct {
2 pid_t child_pid; /* ID ΠΏΡΠΎΡΠ΅ΡΡΠ° */
3 int child_pipefd; /* ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ (Π½Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΡΠΉ) ΠΊΠ°Π½Π°Π» ΠΌΠ΅ΠΆΠ΄Ρ
ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΌ ΠΈ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠ°ΠΌΠΈ */
4 int child_status; /* 0 = Π³ΠΎΡΠΎΠ²ΠΎ */
5 long child_count; /* ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌΡΡ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠΉ */
6 } Child;
7 Child *cptr; /* ΠΌΠ°ΡΡΠΈΠ² ΡΡΡΡΠΊΡΡΡ Child */
ΠΡ Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΠΌ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π΄ΠΎΡΠ΅ΡΠ½Π΅Π³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ°, Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠ°Π½Π°Π»Π° (pipe) ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ°, ΡΠ²ΡΠ·Π°Π½Π½ΠΎΠ³ΠΎ Ρ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΌ, ΡΡΠ°ΡΡΡ Π΄ΠΎΡΠ΅ΡΠ½Π΅Π³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ° ΠΈ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌΡΡ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠΌ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈΡ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠΉ. ΠΡΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π²ΡΠ²ΠΎΠ΄ΠΈΡΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠΌ ΡΠΈΠ³Π½Π°Π»Π° SIGINT ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² ΠΌΠ΅ΠΆΠ΄Ρ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΌΠΈ ΠΏΡΠΎΡΠ΅ΡΡΠ°ΠΌΠΈ.
Π Π°ΡΡΠΌΠΎΡΡΠΈΠΌ ΡΠ½Π°ΡΠ°Π»Π° ΡΡΠ½ΠΊΡΠΈΡ child_make, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π° Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 30.17. ΠΡ ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΠΊΠ°Π½Π°Π» ΠΈ Π΄ΠΎΠΌΠ΅Π½Π½ΡΠΉ ΡΠΎΠΊΠ΅Ρ Unix (ΡΠΌ. Π³Π»Π°Π²Ρ 14) ΠΏΠ΅ΡΠ΅Π΄ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ ΡΡΠ½ΠΊΡΠΈΠΈ fork. ΠΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΡΠΎΠ·Π΄Π°Π½ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ, ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ Π·Π°ΠΊΡΡΠ²Π°Π΅Ρ ΠΎΠ΄ΠΈΠ½ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ (sockfd[1]), Π° Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ Π·Π°ΠΊΡΡΠ²Π°Π΅Ρ Π΄ΡΡΠ³ΠΎΠΉ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ (sockfd[0]). ΠΠΎΠ»Π΅Π΅ ΡΠΎΠ³ΠΎ, Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅Ρ ΡΠ²ΠΎΠΉ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ ΠΊΠ°Π½Π°Π»Π° (sockfd[1]) ΠΊ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΌΡ ΠΏΠΎΡΠΎΠΊΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ°Ρ , ΡΠ°ΠΊ ΡΡΠΎ ΠΊΠ°ΠΆΠ΄ΡΠΉ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ ΠΏΡΠΎΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΡΡΠΎ ΡΡΡΡΠΎΠΉΡΡΠ²ΠΎ Π΄Π»Ρ ΡΠ²ΡΠ·ΠΈ Ρ ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠΌ. ΠΡΠΎΡ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ ΠΏΡΠΎΠΈΠ»Π»ΡΡΡΡΠΈΡΠΎΠ²Π°Π½ ΡΡ Π΅ΠΌΠΎΠΉ, ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΉ Π½Π° ΡΠΈΡ. 30.3.
ΠΠΈΡΡΠΈΠ½Π³ 30.17. Π€ΡΠ½ΠΊΡΠΈΡ child_make: ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ° Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠ° Π² ΡΠ΅ΡΠ²Π΅ΡΠ΅ Ρ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΠΌ ΠΏΠΎΡΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ²
//server/child05.c
1 #include "unp.h"
2 #include "child.h"
3 pid_t
4 child_make(int i, int listenfd, int addrlen)
5 {
6 int sockfd[2];
7 pid_t pid;
8 void child_main(int, int, int);
9 Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);
10 if ((pid = Fork()) > 0) {
11 Close(sockfd[1]);
12 cptr[i].child_pid = pid;
13 cptr[i].child_pipefd = sockfd[0];
14 cptr[i].child_status = 0;
15 return (pid); /* ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ */
16 }
17 Dup2(sockfd[1], STDERR_FILENO); /* ΠΊΠ°Π½Π°Π» ΠΎΡ Π΄ΠΎΡΠ΅ΡΠ½Π΅Π³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ° ΠΊ
ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΎΠΌΡ */
18 Close(sockfd[0]);
19 Close(sockfd[1]);
20 Close(listenfd); /* Π΄ΠΎΡΠ΅ΡΠ½Π΅ΠΌΡ ΠΏΡΠΎΡΠ΅ΡΡΡ Π½Π΅ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ, ΡΡΠΎΠ±Ρ
ΠΎΠ½ Π±ΡΠ» ΠΎΡΠΊΡΡΡ */
21 child_main(i, listenfd, addrlen); /* Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π·Π°Π²Π΅ΡΡΠ°Π΅ΡΡΡ */
22 }
Π ΠΈΡ. 30.3. ΠΠ°Π½Π°Π» ΠΏΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΉ ΠΈ ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ Π·Π°ΠΊΡΡΠ»ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΊΠΎΠ½Π΅Ρ
ΠΠΎΡΠ»Π΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π²ΡΠ΅Ρ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΡ Π΅ΠΌΡ, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΡΡ Π½Π° ΡΠΈΡ. 30.4. ΠΡ Π·Π°ΠΊΡΡΠ²Π°Π΅ΠΌ ΠΏΡΠΎΡΠ»ΡΡΠΈΠ²Π°Π΅ΠΌΡΠΉ ΡΠΎΠΊΠ΅Ρ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π΄ΠΎΡΠ΅ΡΠ½Π΅ΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠ΅, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ accept. ΠΡ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ Π½Π° ΡΠΈΡΡΠ½ΠΊΠ΅, ΡΡΠΎ ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΠΏΡΠΎΡΠ»ΡΡΠΈΠ²Π°Π΅ΠΌΡΠΉ ΡΠΎΠΊΠ΅Ρ, Π° ΡΠ°ΠΊΠΆΠ΅ Π²ΡΠ΅ Π΄ΠΎΠΌΠ΅Π½Π½ΡΠ΅ ΡΠΎΠΊΠ΅ΡΡ. ΠΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ³Π°Π΄Π°ΡΡΡΡ, ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΡΡΠ½ΠΊΡΠΈΡ select Π΄Π»Ρ ΠΌΡΠ»ΡΡΠΈΠΏΠ»Π΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π²ΡΠ΅Ρ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΎΠ².
Π ΠΈΡ. 30.4. ΠΠ°Π½Π°Π»Ρ ΠΏΠΎΡΠ»Π΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π²ΡΠ΅Ρ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ²
Π Π»ΠΈΡΡΠΈΠ½Π³Π΅ 30.18 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° ΡΡΠ½ΠΊΡΠΈΡ main. Π ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΡ Π²Π΅ΡΡΠΈΠΉ ΡΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ, Π² Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π² ΠΏΠ°ΠΌΡΡΠΈ ΡΠ°Π·ΠΌΠ΅ΡΠ°ΡΡΡΡ Π²ΡΠ΅ Π½Π°Π±ΠΎΡΡ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΎΠ² ΠΈ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π½Π°Π±ΠΎΡΠ΅ Π²ΠΊΠ»ΡΡΠ΅Π½Ρ Π²ΡΠ΅ Π±ΠΈΡΡ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ ΠΏΡΠΎΡΠ»ΡΡΠΈΠ²Π°Π΅ΠΌΠΎΠΌΡ ΡΠΎΠΊΠ΅ΡΡ ΠΈ ΠΊΠ°Π½Π°Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π΄ΠΎΡΠ΅ΡΠ½Π΅Π³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ°. ΠΡΡΠΈΡΠ»ΡΠ΅ΡΡΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠ° ΠΈ Π²ΡΠ΄Π΅Π»ΡΠ΅ΡΡΡ ΠΏΠ°ΠΌΡΡΡ Π΄Π»Ρ ΠΌΠ°ΡΡΠΈΠ²Π° ΡΡΡΡΠΊΡΡΡ Child. ΠΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠΈΠΊΠ» Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ select.
ΠΠΈΡΡΠΈΠ½Π³ 30.18. Π€ΡΠ½ΠΊΡΠΈΡ main, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠ°Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠ°
//server/serv05.c
1 #include "unp.h"
2 #include "child.h"
3 static int nchildren;
4 int
5 main(int argc, char **argv)
6 {
7 int listenfd, i, navail, maxfd, nsel, connfd, rc;
8 void sig_int(int);
9 pid_t child_make(int, int, int);
10 ssize_t n;
11 fd_set rset, masterset;
12 socklen_t addrlen, clilen;
13 struct sockaddr *cliaddr;
14 if (argc == 3)
15 listenfd = Tcp_listen(NULL, argv[1], &addrlen);
16 else if (argc == 4)
17 listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
18 else
19 err_quit("usage; serv05 [ <host> ] <port#> <#children>");
20 FD_ZERO(&masterset);
21 FD_SET(listenfd, &masterset);
22 maxfd = listenfd;
23 cliaddr = Malloc(addrlen);
24 nchildren = atoi(argv[argc - 1]);
25 navail = nchildren;
26 cptr = Calloc(nchildren, sizeof(Child));
27 /* ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² */
28 for (i = 0; i < nchildren; i++) {
29 child_make(i, listenfd, addrlen); /* ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ
Π·Π°Π²Π΅ΡΡΠ°Π΅ΡΡΡ */
30 FD_SET(cptr[i].child_pipefd, &masterset);
31 maxfd = max(maxfd, cptr[i].child_pipefd);
32 }
33 Signal(SIGINT, sig_int);
34 for (;;) {
35 rset = masterset;
36 if (navail <= 0)
37 FD_CLR(listenfd, &rset); /* Π²ΡΠΊΠ»ΡΡΠ°Π΅ΠΌ, Π΅ΡΠ»ΠΈ Π½Π΅Ρ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΡΡ
Π΄ΠΎΡΠ΅ΡΠ½ΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² */
38 nsel = Select(maxfd + 1, &rset, NULL, NULL, NULL);
39 /* ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π½ΠΎΠ²ΡΡ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠΉ */
40 if (FD_ISSET(listenfd, &rset)) {
41 clilen = addrlen;
42 connfd = Accept(listenfd, cliaddr, &clilen);
43 for (i = 0; i < nchildren; i++)
44 if (cptr[i].child_status == 0)
45 break; /* ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΡΠΉ */
46 if (i == nchildren)
47 err_quit("no available children");
48 cptr[i].child_status = 1; /* ΠΎΡΠΌΠ΅ΡΠ°Π΅ΠΌ ΡΡΠΎΡ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ ΠΊΠ°ΠΊ
Π·Π°Π½ΡΡΡΠΉ */
49 cptr[i].child_count++;
50 navail--;
51 n = Write_fd(cptr[i].child_pipefd, 1, connfd);
52 Close(connfd);
53 if (--nsel == 0)
54 continue; /* Ρ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°ΠΌΠΈ select() Π·Π°ΠΊΠΎΠ½ΡΠ΅Π½ΠΎ */
55 }
56 /* ΠΏΠΎΠΈΡΠΊ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΠ²ΡΠΈΡ ΡΡ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² */
57 for (i = 0; i < nchildren; i++) {
58 if (FD_ISSET(cptr[i].child_pipefd, &rset)) {
59 if ((n = Read(cptr[i].child_pipefd, &rc, 1)) == 0)
60 err_quit("child %d terminated unexpectedly", i);
61 cptr[i].child_status = 0;
62 navail++;
63 if (--nsel == 0)
64 break; /* Ρ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°ΠΌΠΈ select() Π·Π°ΠΊΠΎΠ½ΡΠ΅Π½ΠΎ */
65 }
66 }
67 }
68 }