void home_draw() { home_page(); getch(); }
int main(int argc, char *argv[]) { int i, fd, n, maxnconn, flags, error; char buf[MAXLINE]; fd_set rs, ws; if (argc < 5) err_quit("usage: web <#conn> <hostname> <homepage> <file1> ..."); maxnconn = atoi(argv[1]); nfiles = min(argc - 4, MAXFILES); for (i = 0; i < nfiles; i++) { file[i].f_name = argv[i+4]; file[i].f_host = argv[2]; file[i].f_flags = 0; } printf("nfiles = %d\n", nfiles); home_page(argv[2], argv[3]); nlefttoread = nlefttoconn = nfiles; nconn = 0; Signal(SIGCHLD, sig_chld); for (i = 0; i < maxnconn; i++) { if (Fork() == 0) { /*child */ printf("child %d started\n", getpid()); home_page(file[i].f_host, file[i].f_name); exit(0); } file[i].f_flags = F_DONE; } while (nlefttoread > 0) { pause(); } printf("all finished\n"); return(0); }
static void sig_chld(int signo) { int i; pid_t pid; while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) { nlefttoread--; printf("child %d terminated\n", pid); for (i = 0; i < nfiles; i++) if (file[i].f_flags == 0) break; if (i != nfiles) { if (Fork() ==0) { printf("child %d started\n", getpid()); home_page(file[i].f_host, file[i].f_name); exit(0); } file[i].f_flags = F_DONE; } } return; }
int main(int argc, char **argv) { int i, fd, n, maxnconn, flags, error, ret, index; char buf[MAXLINE]; fd_set rs, ws; if (argc < 5) err_quit("usage: web <#conns> <hostname> <homepage> <file1> ..."); maxnconn = atoi(argv[1]); nfiles = min(argc - 4, MAXFILES); for (i = 0; i < nfiles; i++) { file[i].f_name = argv[i + 4]; file[i].f_host = argv[2]; file[i].f_flags = 0; } printf("nfiles = %d\n", nfiles); home_page(argv[2], argv[3]); kq = kqueue(); maxfd = -1; nlefttoread = nlefttoconn = nfiles; nconn = 0; /* end web1 */ /* include web2 */ while (nlefttoread > 0) { while (nconn < maxnconn && nlefttoconn > 0) { /* 4find a file to read */ for (i = 0 ; i < nfiles; i++) if (file[i].f_flags == 0) break; if (i == nfiles) err_quit("nlefttoconn = %d but nothing found", nlefttoconn); start_connect(&file[i]); nconn++; nlefttoconn--; } struct kevent events[2]; ret = kevent(kq, NULL, 0, events, nfiles, NULL); for (i = 0; i < ret; i++) { //fd = file[i].f_fd; struct kevent event = events[i]; //kqueue返回的events list事件是不按照顺序的。所以要根据event找到file index。这一点跟select有很大的不同,因为select是按照顺序的 index = find_file_index_by_event(event); flags = file[index].f_flags; if (flags == 0 || flags & F_DONE) continue; int fd = event.ident; int avail_bytes = event.data; if (flags & F_CONNECTING && event.filter == EVFILT_WRITE) { n = sizeof(error); //todo 这里不加socklen_t就编译不通过! ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&n); if ( ret < 0 || error != 0) { err_ret("nonblocking connect failed for %s", file[index].f_name); } /* 4connection established */ printf("connection established for %s\n", file[index].f_name); write_get_cmd(&file[index]);/* write() the GET command */ } else if (flags & F_READING && event.filter == EVFILT_READ) { memset(buf, 0, sizeof(buf)); if ( (n = Read(fd, buf, sizeof(buf)-1)) == 0) { printf("end-of-file on %s\n", file[index].f_name); Close(fd); file[index].f_flags = F_DONE; /* clears F_READING */ struct kevent changes[1]; EV_SET(&changes[0], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); ret = kevent(kq, changes, 1, NULL, 0, NULL); nconn--; nlefttoread--; } else { buf[n]= '\0'; printf("read %d bytes from %s\n", n, file[index].f_name); printf("buf = %s\n", buf); } } } } exit(0); }
int main(int argc, char **argv) { int i, maxnconn; pthread_t tid; struct file *fptr; if (argc < 5) err_quit("usage: web <#conns> <IPaddr> <homepage> file1 ..."); maxnconn = atoi(argv[1]); nfiles = min(argc - 4, MAXFILES); for (i = 0; i < nfiles; i++) { file[i].f_name = argv[i + 4]; file[i].f_host = argv[2]; file[i].f_flags = 0; } printf("nfiles = %d\n", nfiles); home_page(argv[2], argv[3]); nlefttoread = nlefttoconn = nfiles; nconn = 0; /* include web2 */ while (nlefttoread > 0) { while (nconn < maxnconn && nlefttoconn > 0) { /* 4find a file to read */ for (i = 0 ; i < nfiles; i++) if (file[i].f_flags == 0) break; if (i == nfiles) err_quit("nlefttoconn = %d but nothing found", nlefttoconn); file[i].f_flags = F_CONNECTING; Pthread_create(&tid, NULL, &do_get_read, &file[i]); file[i].f_tid = tid; nconn++; nlefttoconn--; } /* 4Wait for thread to terminate */ Pthread_mutex_lock(&ndone_mutex); while (ndone == 0) Pthread_cond_wait(&ndone_cond, &ndone_mutex); for (i = 0; i < nfiles; i++) { if (file[i].f_flags & F_DONE) { Pthread_join(file[i].f_tid, (void **) &fptr); if (&file[i] != fptr) err_quit("file[i] != fptr"); fptr->f_flags = F_JOINED; /* clears F_DONE */ ndone--; nconn--; nlefttoread--; printf("thread %d for %s done\n", fptr->f_tid, fptr->f_name); } } Pthread_mutex_unlock(&ndone_mutex); } exit(0); }
int main(int argc,char **argv) { int i,n,maxnconn; pthread_t tid; struct file *fptr; if (argc < 5) { fprintf(stderr,"usage: web <#conns> <IPaddr> <homepage> file1 ...\n"); exit(-1); } // 設定連線個數,把字串轉成數字 maxnconn = atoi(argv[1]); // 設定要處理的檔案個數,參數個數減掉前四個必要參數,剩下的都是file名稱 nfiles = (argc - 4 < MAXFILES)?argc-4:MAXFILES; for (i=0;i<nfiles;i++) { file[i].f_name = argv[i+4]; // 檔案名稱 file[i].f_host = argv[2]; // 設定server ip file[i].f_flags = 0; // 為0,表示這一個檔案還沒有被處理 } // 列印出來要處理的檔案個數 printf("nfiles = %d\n",nfiles); home_page(argv[2],argv[3]); // 剩下要去[讀取的],[要準備連接的],[一共要讀取的檔案] nlefttoread = nlefttoconn = nfiles; // 目前連接數 nconn = 0; // show the main processing loop of the main thread while (nlefttoread > 0) { while (nconn < maxnconn && nlefttoconn > 0) { // find a file to read for (i=0;i<nfiles;i++) { if (file[i].f_flags ==0) // 為0表示還沒有被處理的檔案 break; } if (i==nfiles) { // 若這一個條件成立,表示所有的檔案都被處理完,或正在處理中 fprintf(stderr,"nlefttoconn = %d but nothing found",nlefttoconn); exit(-1); // 直接中斷程式這樣對嗎? } file[i].f_flags = F_CONNECTING; // 正在連線中 pthread_create(&tid,NULL,do_get_read,&file[i]); // 產生一個thread,並執行do_get_read(),參數為file[i] file[i].f_tid = tid; // 設定處理這一個file的thread id是哪一個 nconn++; // 增加一個連線數 nlefttoconn--; // 減少剩下要被連線的個數 } // wait for thread to terminate pthread_mutex_lock(&ndone_mutex); while (ndone==0) { pthread_cond_wait(&ndone_cond,&ndone_mutex); // 跑去睡覺,等待別的thread叫醒 } for (i=0;i<nfiles;i++) { if (file[i].f_flags & F_DONE) { pthread_join(file[i].f_tid,(void **) &fptr); if (&file[i] != fptr) { fprintf(stderr,"file[i] != fptr"); exit(-1); } fptr->f_flags = F_JOINED; // clears F_DONE ndone--; // 應該是處理完一個,所以,連線數減一 nconn--; // 減少還要處理的檔案個數 nlefttoread--; printf("thread %d for %s done\n",fptr->f_tid,fptr->f_name); } } pthread_mutex_unlock(&ndone_mutex); // 解除ndone_mutex } exit(0); }
int main(int argc, char **argv) { int i, fd, n, maxnconn, flags, error; char buf[MAXLINE]; fd_set rs, ws; if (argc < 5) { fprintf(stderr, "usage: web <#conns> <hostname> <homepage> <file1> ...\n"); exit(1); } maxnconn = atoi(argv[1]); nfiles = min(argc - 4, MAXFILES); for (i = 0; i < nfiles; i++) { file[i].f_name = argv[i + 4]; file[i].f_host = argv[2]; file[i].f_flags = 0; } printf("nfiles = %d\n", nfiles); home_page(argv[2], argv[3]); FD_ZERO(&rset); FD_ZERO(&wset); maxfd = -1; nlefttoread = nlefttoconn = nfiles; nconn = 0; /* end web1 */ /* include web2 */ while (nlefttoread > 0) { while (nconn < maxnconn && nlefttoconn > 0) { /* 4find a file to read */ for (i = 0 ; i < nfiles; i++) if (file[i].f_flags == 0) break; if (i == nfiles) { fprintf(stderr, "nlefttoconn = %d but nothing found\n", nlefttoconn); exit(1); } start_connect(&file[i]); nconn++; nlefttoconn--; } rs = rset; ws = wset; if ((n = select(maxfd+1, &rs, &ws, NULL, NULL)) < 0) { perror("select error"); exit(1); } for (i = 0; i < nfiles; i++) { flags = file[i].f_flags; if (flags == 0 || flags & F_DONE) continue; fd = file[i].f_fd; if (flags & F_CONNECTING && (FD_ISSET(fd, &rs) || FD_ISSET(fd, &ws))) { n = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0 || error != 0) { fprintf(stderr, "nonblocking connect failed for %s: %s\n", file[i].f_name, strerror(errno)); } /* 4connection established */ printf("connection established for %s\n", file[i].f_name); FD_CLR(fd, &wset); /* no more writeability test */ write_get_cmd(&file[i]);/* write() the GET command */ } else if (flags & F_READING && FD_ISSET(fd, &rs)) { if ( (n = read(fd, buf, sizeof(buf))) < 0) { perror("read error"); exit(1); } else if (n == 0) { printf("end-of-file on %s\n", file[i].f_name); if (close(fd) == -1) { perror("close error"); exit(1); } file[i].f_flags = F_DONE; /* clears F_READING */ FD_CLR(fd, &rset); nconn--; nlefttoread--; } else { printf("read %d bytes from %s\n", n, file[i].f_name); } } } } exit(0); }
int main(int argc, char **argv) { int i, maxnconn; pthread_t tid; struct file *fptr; int current; listNode *listNode; for (i = 0; i < MAXFILES; i++) { file[i].f_flags = 0; } context = connectRedis(localhost,port); queue = listCreate(); home_page(HOST, "/"); nlefttoread = nlefttoconn = queue->len; nconn = 0; while (nlefttoconn > 0 || nconn > 0) { printf("lefttoconn: %d, conn:%d\n",nlefttoconn,nconn); current = 0; while (nconn < MAXFILES && nlefttoconn > 0) { for (i = current ; i < MAXFILES; i++) if (file[i].f_flags == 0) { current = i; break; } pthread_mutex_lock(&queue_mutex); listNode = queue->head; if (listNode == NULL) { printf("have some but no!\n"); exit(1); } file[i].f_flags = F_CONNECTING; setFileNameAndHost(listNode->value,file[i].f_name,file[i].f_host); listDelNodeHead(queue); pthread_create(&tid, NULL, &do_get_read, &file[i]); file[i].f_tid = tid; nconn++; nlefttoconn = queue->len; pthread_mutex_unlock(&queue_mutex); } pthread_mutex_lock(&ndone_mutex); while (ndone == 0) pthread_cond_wait(&ndone_cond, &ndone_mutex); for (i = 0; i < MAXFILES; i++) { if (file[i].f_flags & F_DONE) { pthread_join(file[i].f_tid, (void **) &fptr); if (&file[i] != fptr) { printf("file[i]!=ptr\n"); exit(1); } fptr->f_flags = 0; /* clears F_DONE */ ndone--; nconn--; printf("thread %d for name:%s host:%s done\n", fptr->f_tid, fptr->f_name,fptr->f_host); } } pthread_mutex_unlock(&ndone_mutex); } listRelease(queue); disconnectRedis(context); exit(0); }
/**Test for connect delay**/ int main(int argc, char *argv[]) { int i, fd, maxnconn, flags, error; socklen_t n; char buf[MAXLINE]; fd_set rs, ws; if(argc < 5) err_quit("usage: web <#conns> <hostname> <homepage> <file1> ..."); maxnconn = atoi(argv[1]); nfiles = min(argc - 4, MAXFILES); for(i = 0; i < nfiles; i++) { file[i].f_name = argv[i+4]; file[i].f_host = argv[2]; file[i].f_flags = 0; } printf("nfiles = %d\n", nfiles); home_page(argv[2], argv[3]); FD_ZERO(&rset); FD_ZERO(&wset); maxfd = -1; nconn = 0; nlefttoread = nlefttoconn = nfiles; while(nlefttoread > 0) { while(nconn < maxnconn && nlefttoconn > 0) { for(i = 0; i < nfiles; i++) { if(file[i].f_flags == 0) break; if(i == nfiles) err_quit("nlefttoconn = %d but nothing found", nlefttoconn); start_connect(&file[i]); nconn++; nlefttoconn--; } } rs = rset; ws = wset; n = Select(maxfd + 1, &rs, &ws, NULL, NULL); for(i = 0; i < nfiles; i++) { flags = file[i].f_flags; if(flags == 0 || flags & F_DONE) continue; fd = file[i].f_fd; if(flags & F_CONNECTING && (FD_ISSET(fd, &rs) || FD_ISSET(fd, &ws))) { n = sizeof(error); if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0 || error != 0) { err_ret("nonblocking connect failed for %s", file[i].f_name); } printf("connection established for %s\n", file[i].f_name); FD_CLR(fd, &wset); write_get_cmd(&file[i]); } else if(flags & F_READING && FD_ISSET(fd, &rs)) { if((n = read(fd, buf, sizeof(buf))) == 0) { printf("end of file on %s\n", file[i].f_name); close(fd); file[i].f_flags = F_DONE; FD_CLR(fd, &rset); nconn--; nlefttoread--; } else printf("read %d bytes from %s\n", n, file[i].f_name); } } } exit(0); }
int main(int argc, char **argv) { int i, n, maxnconn; pthread_t tid; struct file *fptr; if (argc < 5) err_quit("usage: web <#conns> <IPaddr> <homepage> file1 ..."); maxnconn = atoi(argv[1]); nfiles = min(argc - 4, MAXFILES); for (i = 0; i < nfiles; i++) { file[i].f_name = argv[i + 4]; file[i].f_host = argv[2]; file[i].f_flags = 0; } printf("nfiles = %d\n", nfiles); home_page(argv[2], argv[3]); nlefttoread = nlefttoconn = nfiles; nconn = 0; while (nlefttoread > 0) { /* printf("nconn = %d, nlefttoconn = %d\n", nconn, nlefttoconn); */ while (nconn < maxnconn && nlefttoconn > 0) { /* find a file to read */ for (i = 0 ; i < nfiles; i++) if (file[i].f_flags == 0) break; if (i == nfiles) err_quit("nlefttoconn = %d but nothing found", nlefttoconn); if ( (n = pthread_create(&tid, NULL, &do_get_read, &file[i])) != 0) errno = n, err_sys("pthread_create error"); printf("created thread %d\n", tid); file[i].f_tid = tid; file[i].f_flags = F_CONNECTING; nconn++; nlefttoconn--; } thr_yield(); /* See if one of the threads is done */ if ( (n = pthread_mutex_lock(&ndone_mutex)) != 0) errno = n, err_sys("pthread_mutex_lock error"); if (ndone > 0) { for (i = 0; i < nfiles; i++) { if (file[i].f_flags & F_DONE) { if ( (n = pthread_join(file[i].f_tid, (void **) &fptr)) != 0) errno = n, err_sys("pthread_join error"); if (&file[i] != fptr) err_quit("file[i] != fptr"); fptr->f_flags = F_JOINED; /* clears F_DONE */ ndone--; nconn--; nlefttoread--; printf("thread id %d for %s done\n", file[i].f_tid, fptr->f_name); } } } if ( (n = pthread_mutex_unlock(&ndone_mutex)) != 0) errno = n, err_sys("pthread_mutex_unlock error"); } exit(0); }
void home_draw() { home_page(); }