1. Signal processing problems
The same signal is processed in sequence. The possible problem is that two or more sig1 signals are generated while processing the sig1 signal. After processing the original sig1 signal, then process one sig1 signal. Therefore, if the same signal is used, the problem of packet loss occurs. After a son retires, the program is processing handler (). If two sons are retired at this time, the resources of one son cannot be recycled, which is called a zombie process.
For different signals, priority is given to the latter. After processing, the latter will be processed back to the previous one. For example, if sig2 is generated while processing sig1, it will process sig2 first. After processing sig2, it will continue to process sig1.
2. Solution
In the registered signal processing function, loop is used, and waitpid is used in the loop to recycle sub-process resources. As long as you enter the signal processing function, the signal processing function can recycle all the fork son resources. Note: The waitpid should be set to non-blocking mode. Otherwise, when a loop is entered, if no sub-process exits, it will be blocked in the signal processing function.
3. Wait and waitpid
Wait must be in blocking mode. Therefore, in the signal processing function, there is a problem with while1 {Wait (null)}. If a son does not return after entering the signal processing function, it will always be blocked here.
Waitpid can be in blocking or non-blocking mode.
4. Select and accept
The two return-1 when receiving the signal.
If the program fails to receive signals that are not processed by the system by default, the system certainly does not return-1. In other words, sigchld is a signal that the system does not process by default. If you do not register a signal processing function for it, select and accept will not return-1 when the sub-process exits.
// Server. c
# Include "my_socket.h" # include <sys/Wait. h> # include <signal. h> # include <errno. h> # define my_ip "192.168.1.100" # define my_port 8888 # define size 192 # define msg_size (size-4) extern int errno; typedef struct tag_mag {int msg_len; // record the actual size of msg_buf char msg_buf [msg_size]; // the space occupied by msg_buf is 188 bytes} MSG, * PMSG; void my_handle (INT num) {/* waitpid parameter: *-1 indicates that every son is recycled * null indicates that the exit return value of the child process is not concerned * wnohang: Wait no hang non-blocking Mode * waitpid return value: *-1 indicates that no son is created * 0 indicates that no son exits * greater than 0 indicates that a son exits */while (waitpid (-1, null, wnohang)> 0);} int main (INT argc, char * argv []) {int fd_listen, fd_client; signal (sigchld, my_handle); my_socket (& fd_listen, my_tcp, my_ip, my_port); my_listen (fd_listen, 10); While (fd_client = accept (fd_listen, null, null) {/* The accept can be received if it is not a signal ignored by the program by default, and returns-1 */If (fd_client =-1) {If (errno = eintr) {cont Inue;} else {break; // after the break exits, the father will return. The son will be taken over by init.} Else {If (Fork () = 0) // The fork son is used to communicate with the client {MSG recv_msg; int recvn; while (1) {memset (& recv_msg, 0, sizeof (MSG);/* In my_socket.c, the length of my_recv received and the length of my_send sent must be an exact value * The length entered in my_recv is less than or equal to the actual length to be received, yes. If it is greater than, it will never return out of the loop */my_recv (& recvn, fd_client, & recv_msg, 4); If (recvn = 0) // when the opposite client exits (closes the socket), the returned value of the system call Recv is 0 {break;} else {my_recv (null, fd_client, & recv_msg.msg_buf, recv_msg.msg_len); my_send (null, fd_client, & recv_msg, 4 + recv_msg.msg_len) ;}} close (fd_client); exit (0) ;}close (fd_client) ;}} return 0 ;}
// Client. c
#include "my_socket.h"#define MY_IP "192.168.1.100"#define MY_PORT 6666#define SER_IP "192.168.1.100"#define SER_PORT 8888#define SIZE 192#define MSG_SIZE (SIZE - 4)typedef struct tag_mag { int msg_len ; char msg_buf[MSG_SIZE];//188}MSG, *pMSG;int main(int argc, char* argv[]){ int sfd ; my_socket(&sfd, MY_TCP, MY_IP, MY_PORT); my_connect(sfd, SER_IP, SER_PORT); MSG my_msg ; while(memset(&my_msg, 0, sizeof(MSG)), fgets(my_msg.msg_buf, MSG_SIZE, stdin)!= NULL) { my_msg.msg_len = strlen(my_msg.msg_buf); my_send(NULL, sfd, &my_msg, 4 + my_msg.msg_len ); memset(&my_msg, 0, sizeof(MSG)); my_recv(NULL, sfd, &my_msg, 4); my_recv(NULL, sfd, &my_msg.msg_buf, my_msg.msg_len); printf("recv from server : %s \n", my_msg.msg_buf); } close(sfd);}
Process pool early stage