select function may upate timeout parameter in linux.why it is 'may update'? -
my operating system centos 6.4.
for select linux programmer's manual says: "select may update timeout parameter indicate how time left...."
i wonder why 'may' rather 'must'? there system version or kernel version?
i make test. test_code01.cpp
#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <resolv.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <fcntl.h> #include <sys/time.h> #include <pthread.h> #define bufsize 1024 struct timeval g_timeout; int main(int argc, char* argv[]) { int sock_clientfd, ret_recvsize, i; struct sockaddr_in dest, mine; char buffer[bufsize + 1]; // create socket fd if ((sock_clientfd = socket(af_inet, sock_stream, 0)) < 0) { perror("socket"); exit(exit_failure); } // init server address client connetct to. bzero(&dest, sizeof(dest)); dest.sin_family = af_inet; dest.sin_port = htons(9567); if(argc != 2) { printf("usage: %s <dest ip>\n", argv[0]); printf("usage: %s 127.0.0.1\n", argv[0]); return -1; } printf("-----\n"); if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) { perror(argv[1]); exit(1); } // connect server printf("will connect!\n"); if (connect(sock_clientfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) { perror("connect "); exit(exit_failure); } int ret_select = 0; fd_set readfds; fd_set(sock_clientfd, &readfds); g_timeout.tv_sec = 3; g_timeout.tv_usec = 0; while(1) { ret_select = select(sock_clientfd + 1, &readfds, null, null, &g_timeout); // becasue select can update timeout, need set value timeout. // g_timeout.tv_sec = 3; // g_timeout.tv_usec = 0; // recover sock_clienfd state fd_set(sock_clientfd, &readfds); if(ret_select == 0) { printf("select wait timeout.\n"); continue; } bzero(buffer, bufsize + 1); ret_recvsize = recv(sock_clientfd, buffer, bufsize, 0); if(ret_recvsize > 0) { printf("get %d message:%s", strlen(buffer), buffer); ret_recvsize=0; } else { printf("no data server\n"); } } // close sock_clientfd close(sock_clientfd); return 0; }
i execute test_code01.cpp, , result select wait 3 seconds first times.in opinion, select modify timeout.so modify code follow:
#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <resolv.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <fcntl.h> #include <sys/time.h> #include <pthread.h> #define bufsize 1024 // in order facilitate ovservation data // timeout set global varible struct timeval g_timeout; void* thredproc_looktimeout(void*) { while(1) { printf("left time: %ds %dms\n", g_timeout.tv_sec, g_timeout.tv_usec); } } int main(int argc, char* argv[]) { int sock_clientfd, ret_recvsize, i; struct sockaddr_in dest, mine; char buffer[bufsize + 1]; // create socket fd if ((sock_clientfd = socket(af_inet, sock_stream, 0)) < 0) { perror("socket"); exit(exit_failure); } // init server address client connetct to. bzero(&dest, sizeof(dest)); dest.sin_family = af_inet; dest.sin_port = htons(9567); if(argc != 2) { printf("usage: %s <dest ip>\n", argv[0]); printf("usage: %s 127.0.0.1\n", argv[0]); return -1; } printf("-----\n"); if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) { perror(argv[1]); exit(1); } // connect server printf("will connect!\n"); if (connect(sock_clientfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) { perror("connect "); exit(exit_failure); } int ret_select = 0; fd_set readfds; fd_set(sock_clientfd, &readfds); printf("fdset add fd start+++\n"); for(int = 0; < 2000; i++) { fd_set(1025+i, &readfds); } printf("%d--%s\n", errno, strerror(errno)); printf("fdset add 2000 fd finish...\n"); g_timeout.tv_sec = 3; g_timeout.tv_usec = 0; /** * timeout left time create thread **/ pthread_t tid; int ret_pthreadcreate = pthread_create(&tid, null, thredproc_looktimeout, null); printf("pthread_create return value %d\n", ret_pthreadcreate); while(1) { ret_select = select(sock_clientfd + 1, &readfds, null, null, &g_timeout); // becasue select can update timeout, need set value timeout. g_timeout.tv_sec = 3; g_timeout.tv_usec = 0; // recover sock_clienfd state fd_set(sock_clientfd, &readfds); if(ret_select == 0) { printf("select wait timeout.\n"); continue; } bzero(buffer, bufsize + 1); ret_recvsize = recv(sock_clientfd, buffer, bufsize, 0); if(ret_recvsize > 0) { printf("get %d message:%s", strlen(buffer), buffer); ret_recvsize=0; } else { printf("no data server\n"); } } // close sock_clientfd close(sock_clientfd); return 0; }
i think should see change in timeout in thredproc_looktimeout.but no change.i don't know why?
the manual page means on return timeout might updated indicate amount of time left. absolutely doesn't mean timeout updated while wait still in progress.
and if was, there no possible way detect it. attempt threads won't work because has no synchronization of kind. among other problems, compiler optimize while
loop read g_timeout
once. , there no conceivable synchronization mechanism use.
Comments
Post a Comment