int testThreadPool() { #ifdef __LINUX__ cout << "this is linux" << endl; #endif #ifdef __WINDOWS__ cout << "this is windows" << endl; #endif ThreadPool pool; pool.Run(8); pool.AddTask(new MyTask()); MySignal si; for (int i = 0; i < 8; ++i) //while (running) { pool.AddTask(new MyTask()); cout << "add task ...." << endl; //Timer::Sleep(500); } int sec = 0; while (running) { cout << "wait sec " << sec++ << endl; Timer::Sleep(1000); } return 0; }
void RayTrace() { const uint32_t kSamples = g_width*g_height; ThreadPool threadPool; const uint32_t kTileSize = 16; const uint32_t kNumJobs = ceil(g_width / float(kTileSize)) * ceil(g_height / float(kTileSize)); vector<RayJob> jobs(kNumJobs); // create camera const Camera camera(TransformMatrix(g_camDir, g_camPos), 45.0f, 0.1f, 10000.0f, g_width, g_height); uint32_t jobIndex = 0; double startTime = GetSeconds(); // create thread jobs for (uint32_t y=0; y < g_height; y += kTileSize) { uint32_t top = y; uint32_t bottom = min(top+kTileSize, g_height); for (uint32_t x=0; x < g_width; x += kTileSize) { RayJob& job = jobs[jobIndex++]; job.m_rect = Rect(x, min(x+kTileSize, g_width), top, bottom); job.m_camera = camera; job.m_scene = g_scene; job.m_samplesPerPixel = 1; job.m_output = &g_pixels[0]; job.m_outputPitch = g_width; threadPool.AddTask(RayTraceThreadFunc, &job); } } threadPool.Run(g_numWorkers); threadPool.Wait(); // print out trace time every 10 frames double endTime = GetSeconds(); /* cout << "Nodes checked: " << g_nodesChecked << endl; cout << "Tris checked: " << g_trisChecked << endl; g_trisChecked = 0; g_nodesChecked = 0; */ ++g_iterations; Colour* presentMem = g_pixels; if (g_mode == ePathTrace) { float s = g_exposure / g_iterations; for (uint32_t i=0; i < g_width*g_height; ++i) { g_filtered[i] = LinearToSrgb(g_pixels[i] * s); } presentMem = g_filtered; } static uint32_t s_counter=0; if (s_counter % 10) { cout << "Trace took: " << (endTime-startTime)*1000.0f << "ms" << " rays/s: " << g_width*g_height/(endTime-startTime) << endl; } ++s_counter; glDisable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glPixelZoom(float(g_windowWidth)/g_width, float(g_windowHeight)/g_height); glDrawPixels(g_width,g_height,GL_RGBA,GL_FLOAT, presentMem); }
int main() { char neterr[ANET_ERR_LEN]; struct epoll_event ev; int listenfd; if(!db.Open("mydb")){ cerr<<"db open failed:"<<endl; return 0; } signal(SIGPIPE, SIG_IGN); //ignore sigpipe to prevent server shut down thread_pool.Run(); if((listenfd = anetTcpServer(neterr, 9999, NULL)) == ANET_ERR){ fprintf(stderr, "%s\n", neterr); exit(1); } anetNonBlock(neterr, listenfd); if((epfd = epoll_create(MAX_CLIENTS)) < 0){ perror("epoll_create"); exit(1); } ev.events = EPOLLIN; ev.data.fd =listenfd; if(epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev)<0){ perror("epoll_ctl"); exit(1); } for(;;){ int nfds = epoll_wait(epfd, events, MAX_CLIENTS, -1); for(int i = 0; i < nfds; ++i) { int fd = events[i].data.fd; if(fd == listenfd) { struct sockaddr_in cliaddr; socklen_t addrlen = sizeof(cliaddr); int connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &addrlen); if(connfd < 0){ if(errno == ECONNABORTED) //connection aborted, ignore it continue; else if(errno == EAGAIN) //no connections are ready to be accepted continue; else{ //error happened in accept, report it perror("accept"); continue; } } fprintf(stderr, "a new connfd: %d\n", connfd); anetNonBlock(neterr, connfd); ev.events = EPOLLIN; ev.data.fd = connfd; if (epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev) < 0) { perror("epoll_ctl"); return -1; } clients[connfd].fd = connfd; nclients++; } else if(events[i].events & EPOLLIN) { int n; char* rbuf = clients[fd].readbuf; while ((n = read(fd, rbuf+clients[fd].rpos, MAX_BUFLEN-clients[fd].rpos)) > 0) clients[fd].rpos += n; if (n == 0) { //client has been closed fprintf(stderr, "client has been closed, so server also close it, fd=%d\n", fd); close(fd); nclients--; } if (n<0 && errno != EAGAIN) { perror("read"); close(fd); nclients--; } int res = handle_read_event(&clients[fd]); if(res<0){ //error happened fprintf(stderr, "bad command, res=%d\n", res); close(fd); nclients--; }else if(res>0){ //the command has been hand over to a background thread, nothing to do here }else{ //res == 0, needs more data, continue reading } } else if(events[i].events & EPOLLOUT) { char* wbuf = clients[fd].writebuf; int wend = clients[fd].wend; int n; while (wend>clients[fd].wpos && (n = write(fd, wbuf+clients[fd].wpos, wend-clients[fd].wpos)) > 0) clients[fd].wpos += n; if (n<0 && errno != EAGAIN) { perror("write"); close(fd); nclients--; } if(wend == clients[fd].wpos){ //write finished //no need to rest for next write cause read event handler will do it //register as read event clients[fd].reset_for_next_read(); //reset for read ev.data.fd=fd; ev.events=EPOLLIN; epoll_ctl(epfd,EPOLL_CTL_MOD,fd,&ev); } } else{ //impossible! } } } return 0; }
DWORD WINAPI ThreadPool::ThreadPoolFunc( LPVOID lpThreadParameter ) { ThreadPool *tp = (ThreadPool*)lpThreadParameter; tp->Run(); return 0; }