int main(int argc, char* argv[]) { struct handler_threads_pool* handler_threads = NULL; int socket_desc , client_sock , len, i; struct sockaddr_in server, client; socket_desc = socket(AF_INET , SOCK_STREAM , 0); if (socket_desc == -1) printf("Could not create socket"); server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons( 8888 ); if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) { perror("bind failed. Error"); return 1; } listen(socket_desc , 3); len = sizeof(struct sockaddr_in); Requests_queue* requests = new Requests_queue(&request_mutex, &got_request); assert(requests); handler_threads = init_handler_threads_pool(&request_mutex, &got_request, requests); assert(handler_threads); int num_requests; // количество запросов которых необходимо обработать int num_threads; // количество активных потоков //TODO: выделить отдельный поток под прослушивание сокета и не загружать основной, //в мэин потоке будет выводить лишь статистика по подключениям. //изменится основной цикл, будет использоваться epoll while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&len)) ) { requests->add_request(client_sock); num_requests = requests->get_requests_number(); num_threads = get_handler_threads_number(handler_threads); if (num_requests > HIGH_REQUESTS_WATERMARK && num_threads < MAX_NUM_HANDLER_THREADS) { printf("main: adding thread: '%d' requests, '%d' threads\n", num_requests, num_threads); add_handler_thread(handler_threads); } if (num_requests < LOW_REQUESTS_WATERMARK && num_threads > NUM_HANDLER_THREADS) { printf("main: deleting thread: '%d' requests, '%d' threads\n", num_requests, num_threads); delete_handler_thread(handler_threads); } } delete_handler_threads_pool(handler_threads); delete requests; printf("we are done.\n"); return 0; }
/* like any C program, program's execution begins in main */ int main(int argc, char* argv[]) { int i; /* loop counter */ struct timespec delay; /* used for wasting time */ struct requests_queue* requests = NULL; /* pointer to requests queue */ struct handler_threads_pool* handler_threads = NULL; /* list of handler threads */ /* create the requests queue */ requests = init_requests_queue(&request_mutex, &got_request); assert(requests); /* create the handler threads list */ handler_threads = init_handler_threads_pool(&request_mutex, &got_request, requests); assert(handler_threads); /* create the request-handling threads */ for (i=0; i<NUM_HANDLER_THREADS; i++) { add_handler_thread(handler_threads); } /* run a loop that generates requests */ for (i=0; i<600; i++) { int num_requests; // number of requests waiting to be handled. int num_threads; // number of active handler threads. add_request(requests, i); num_requests = get_requests_number(requests); num_threads = get_handler_threads_number(handler_threads); /* if there are too many requests on the queue, spawn new threads */ /* if there are few requests and too many handler threads, cancel */ /* a handler thread. */ if (num_requests > HIGH_REQUESTS_WATERMARK && num_threads < MAX_NUM_HANDLER_THREADS) { printf("main: adding thread: '%d' requests, '%d' threads\n", num_requests, num_threads); add_handler_thread(handler_threads); } if (num_requests < LOW_REQUESTS_WATERMARK && num_threads > NUM_HANDLER_THREADS) { printf("main: deleting thread: '%d' requests, '%d' threads\n", num_requests, num_threads); delete_handler_thread(handler_threads); } /* pause execution for a little bit, to allow */ /* other threads to run and handle some requests. */ if (rand() > 3*(RAND_MAX/4)) { /* this is done about 25% of the time */ delay.tv_sec = 0; delay.tv_nsec = 1; nanosleep(&delay, NULL); } } /* modify the flag to tell the handler threads no */ /* new requests will be generated. */ { int rc; rc = pthread_mutex_lock(&request_mutex); done_creating_requests = 1; rc = pthread_cond_broadcast(&got_request); rc = pthread_mutex_unlock(&request_mutex); } /* cleanup */ delete_handler_threads_pool(handler_threads); delete_requests_queue(requests); printf("Glory, we are done.\n"); return 0; }