threadpool_t *threadpool_create(int thread_count, int queue_size, int flags) { /* Check for negative or otherwise very big input parameters */ if(thread_count <= 0) thread_count = DEFAULT_THREAD_NUM; if(queue_size <= 0) queue_size = DEFAULT_QUEUE_SIZE; threadpool_t *pool = (threadpool_t *)malloc(sizeof(threadpool_t)); if(pool == NULL) goto err; /* Initialize */ pool->shutdown = pool->started = 0; if((pthread_mutex_init(&(pool->lock), NULL) != 0)) goto err; /* Allocate thread and task queue */ pool->thread_count = thread_count; pool->threads = (thread_t *)malloc(sizeof(thread_t) * thread_count); if(pool->threads == NULL) goto err; /* Start worker threads */ int i = 0; for(i = 0; i < pool->thread_count; i++) { thread_create(pool, queue_size, i); pool->started++; } return pool; err: if(pool) threadpool_free(pool); return NULL; }
threadpool_t *threadpool_create(int min_thr_num, int max_thr_num, int queue_max_size) { int i; threadpool_t *pool = NULL; do{ if((pool = (threadpool_t *)malloc(sizeof(threadpool_t))) == NULL) { printf("malloc threadpool fail"); break; /*跳出do while*/ } pool->min_thr_num = min_thr_num; pool->max_thr_num = max_thr_num; pool->busy_thr_num = 0; pool->live_thr_num = min_thr_num; pool->queue_size = 0; pool->queue_max_size = queue_max_size; pool->queue_front = 0; pool->queue_rear = 0; pool->shutdown = false; pool->threads = (pthread_t *)malloc(sizeof(pthread_t)*max_thr_num); if (pool->threads == NULL) { printf("malloc threads fail"); break; } memset(pool->threads, 0, sizeof(pool->threads)); pool->task_queue = (threadpool_task_t *)malloc(sizeof(threadpool_task_t)*queue_max_size); if (pool->task_queue == NULL) { printf("malloc task_queue fail"); break; } if (pthread_mutex_init(&(pool->lock), NULL) != 0 || pthread_mutex_init(&(pool->thread_counter), NULL) != 0 || pthread_cond_init(&(pool->queue_not_empty), NULL) != 0 || pthread_cond_init(&(pool->queue_not_full), NULL) != 0) { printf("init the lock or cond fail"); break; } /* 启动min_thr_num个work thread */ for (i = 0; i < min_thr_num; i++) { pthread_create(&(pool->threads[i]), NULL, threadpool_thread, (void *)pool); printf("start thread 0x%x...\n", (unsigned int)pool->threads[i]); } pthread_create(&(pool->adjust_tid), NULL, adjust_thread, (void *)pool); return pool; }while(0); threadpool_free(pool); /*前面代码调用失败时,释放poll存储空间*/ return NULL; }
zv_threadpool_t *threadpool_init(int thread_num) { if (thread_num <= 0) { log_err("the arg of threadpool_init must greater than 0"); return NULL; } zv_threadpool_t *pool; if ((pool = (zv_threadpool_t *)malloc(sizeof(zv_threadpool_t))) == NULL) { goto err; } pool->thread_count = 0; pool->queue_size = 0; pool->shutdown = 0; pool->started = 0; pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * thread_num); /* dummy head */ pool->head = (zv_task_t *)malloc(sizeof(zv_task_t)); pool->head->func = NULL; pool->head->arg = NULL; pool->head->next = NULL; if ((pool->threads == NULL) || (pool->head == NULL)) { goto err; } if (pthread_mutex_init(&(pool->lock), NULL) != 0) { goto err; } if (pthread_cond_init(&(pool->cond), NULL) != 0) { pthread_mutex_lock(&(pool->lock)); pthread_mutex_destroy(&(pool->lock)); goto err; } int i, rc; for (i=0; i<thread_num; ++i) { if (pthread_create(&(pool->threads[i]), NULL, threadpool_worker, (void *)pool) != 0) { threadpool_destroy(pool, 0); return NULL; } log_info("thread: %08x started", pool->threads[i]); pool->thread_count++; pool->started++; } return pool; err: if (pool) { threadpool_free(pool); } return NULL; }
threadpool_t *threadpool_create(int thread_count, int queue_size, int flags) { threadpool_t *pool; int i; /* TODO: Check for negative or otherwise very big input parameters */ printf("in func thread %d\n", thread_count); if((pool = (threadpool_t *)malloc(sizeof(threadpool_t))) == NULL) { printf("bingo!\n"); goto err; } /* Initialize */ pool->thread_count = 0; pool->queue_size = queue_size; pool->head = pool->tail = pool->count = 0; pool->shutdown = pool->started = 0; /* Allocate thread and task queue */ pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * thread_count); pool->queue = (threadpool_task_t *)malloc (sizeof(threadpool_task_t) * queue_size); /* Initialize mutex and conditional variable first */ if((pthread_mutex_init(&(pool->lock), NULL) != 0) || (pthread_cond_init(&(pool->notify), NULL) != 0) || (pool->threads == NULL) || (pool->queue == NULL)) { printf("bingo!!\n"); goto err; } /* Start worker threads */ for(i = 0; i < thread_count; i++) { if(pthread_create(&(pool->threads[i]), NULL, threadpool_thread, (void*)pool) != 0) { threadpool_destroy(pool, 0); return NULL; } pool->thread_count++; pool->started++; } return pool; err: if(pool) { threadpool_free(pool); } return NULL; }
threadpool_t *threadpool_create(int thread_count, int queue_size, int flags) { if(thread_count <= 0 || thread_count > MAX_THREADS || queue_size <= 0 || queue_size > MAX_QUEUE) { return NULL; } threadpool_t *pool; int i; /* 申请内存创建内存池对象 */ if((pool = (threadpool_t *)malloc(sizeof(threadpool_t))) == NULL) { goto err; } /* Initialize */ pool->thread_count = 0; pool->queue_size = queue_size; pool->head = pool->tail = pool->count = 0; pool->shutdown = pool->started = 0; /* Allocate thread and task queue */ /* 申请线程数组和任务队列所需的内存 */ pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * thread_count); pool->queue = (threadpool_task_t *)malloc (sizeof(threadpool_task_t) * queue_size); /* Initialize mutex and conditional variable first */ /* 初始化互斥锁和条件变量 */ if((pthread_mutex_init(&(pool->lock), NULL) != 0) || (pthread_cond_init(&(pool->notify), NULL) != 0) || (pool->threads == NULL) || (pool->queue == NULL)) { goto err; } /* Start worker threads */ /* 创建指定数量的线程开始运行 */ for(i = 0; i < thread_count; i++) { if(pthread_create(&(pool->threads[i]), NULL, threadpool_thread, (void*)pool) != 0) { threadpool_destroy(pool, 0); return NULL; } pool->thread_count++; pool->started++; } return pool; err: if(pool) { threadpool_free(pool); } return NULL; }
int threadpool_destroy(threadpool_t *pool, int flags) { int i, err = 0; if(pool == NULL) { return threadpool_invalid; } if(pthread_mutex_lock(&(pool->lock)) != 0) { return threadpool_lock_failure; } do { /* Already shutting down */ if(pool->shutdown) { err = threadpool_shutdown; break; } pool->shutdown = (flags & threadpool_graceful) ? graceful_shutdown : immediate_shutdown; /* Wake up all worker threads */ if((pthread_cond_broadcast(&(pool->notify)) != 0) || (pthread_mutex_unlock(&(pool->lock)) != 0)) { err = threadpool_lock_failure; break; } /* Join all worker thread */ for(i = 0; i < pool->thread_count; i++) { if(pthread_join(pool->threads[i], NULL) != 0) { err = threadpool_thread_failure; } } } while(0); /* Only if everything went well do we deallocate the pool */ if(!err) { threadpool_free(pool); } return err; }
int threadpool_destroy(threadpool_t *pool, int flags) { int i, err = 0; if(pool == NULL) { return threadpool_invalid; } /* 取得互斥锁资源 */ if(pthread_mutex_lock(&(pool->lock)) != 0) { return threadpool_lock_failure; } do { /* Already shutting down */ /* 判断是否已在其他地方关闭 */ if(pool->shutdown) { err = threadpool_shutdown; break; } /* 获取指定的关闭方式 */ pool->shutdown = (flags & threadpool_graceful) ? graceful_shutdown : immediate_shutdown; /* Wake up all worker threads */ /* 唤醒所有因条件变量阻塞的线程,并释放互斥锁 */ if((pthread_cond_broadcast(&(pool->notify)) != 0) || (pthread_mutex_unlock(&(pool->lock)) != 0)) { err = threadpool_lock_failure; break; } /* Join all worker thread */ /* 等待所有线程结束 */ for(i = 0; i < pool->thread_count; i++) { if(pthread_join(pool->threads[i], NULL) != 0) { err = threadpool_thread_failure; } } /* 同样是 do{...} while(0) 结构*/ } while(0); /* Only if everything went well do we deallocate the pool */ if(!err) { /* 释放内存资源 */ threadpool_free(pool); } return err; }
fv_threadpool_t *threadpool_init(int thread_num) { /* TODO: Check for negative or otherwise very big input parameters */ if (thread_num <= 0) { log_err("the arg of threadpool_init must > 0"); return NULL; } /* Initialize */ fv_threadpool_t *pool; if ((pool = (fv_threadpool_t*)malloc(sizeof(fv_threadpool_t))) == NULL) { goto err; } pool->thread_count = 0; pool->queue_size = 0; pool->shutdown = 0; pool->started = 0; /* Allocate thread and task queue */ pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * thread_num); /*此处保留一个空头部,便于插入删除操作*/ pool->head = (fv_task_t *)malloc(sizeof(fv_task_t)); pool->head->func = pool->head->arg = pool->head->next = NULL; /* Initialize mutex and conditional variable first */ if (pthread_mutex_init(&(pool->lock), NULL) != 0 || pthread_cond_init(&(pool->cond), NULL) != 0 || pool->threads == NULL || pool->head == NULL) { goto err; } /* Start worker threads */ int i; for (i = 0; i < thread_num; ++i) { if (pthread_create(&(pool->threads[i]), NULL, threadpool_worker, (void *)pool) != 0) { threadpool_destroy(pool, 0); return NULL; } log_info("thread: %08x started", (unsigned int)pool->threads[i]); pool->thread_count++; pool->started++; } return pool; err: if (pool) { threadpool_free(pool); } return NULL; }
int threadpool_destroy(fv_threadpool_t *pool, int graceful) { int err = 0; if (pool == NULL) { log_err("pool == NULL"); return fv_tp_invalid; } /* to set the showdown flag of pool and wake up all thread */ if (pthread_mutex_lock(&(pool->lock)) != 0) { return fv_tp_lock_fail; } do { if (pool->shutdown) { err = fv_tp_already_shutdown; break; } pool->shutdown = graceful ? graceful_shutdown : immediate_shutdown; /* wake up all worker threads */ if (pthread_cond_broadcast(&(pool->cond)) != 0) { err = fv_tp_cond_broadcast; break; } if (pthread_mutex_unlock(&(pool->lock)) != 0) { err = fv_tp_lock_fail; break; } int i; /* join all worker threads */ for (i = 0; i < pool->thread_count; ++i) { if (pthread_join(pool->threads[i], NULL) != 0) { err = fv_tp_thread_fail; } log_info("thread %08x exit", (unsigned int)pool->threads[i]); } } while (0); /* Only if everything went well do we deallocate the pool */ if (!err) { threadpool_free(pool); } return err; }
int threadpool_destroy(zv_threadpool_t *pool, int graceful) { int err = 0; if (pool == NULL) { log_err("pool == NULL"); return zv_tp_invalid; } if (pthread_mutex_lock(&(pool->lock)) != 0) { return zv_tp_lock_fail; } do { // set the showdown flag of pool and wake up all thread if (pool->shutdown) { err = zv_tp_already_shutdown; break; } pool->shutdown = (graceful)? graceful_shutdown: immediate_shutdown; if (pthread_cond_broadcast(&(pool->cond)) != 0) { err = zv_tp_cond_broadcast; break; } if (pthread_mutex_unlock(&(pool->lock)) != 0) { err = zv_tp_lock_fail; break; } int i; for (i=0; i<pool->thread_count; i++) { if (pthread_join(pool->threads[i], NULL) != 0) { err = zv_tp_thread_fail; } log_info("thread %08x exit", pool->threads[i]); } } while(0); if (!err) { pthread_mutex_destroy(&(pool->lock)); pthread_cond_destroy(&(pool->cond)); threadpool_free(pool); } return err; }
int threadpool_destroy(threadpool_t *pool) { int i; if (pool == NULL) { return -1; } pool->shutdown = true; /*先销毁管理线程*/ pthread_join(pool->adjust_tid, NULL); for (i = 0; i < pool->live_thr_num; i++) { /*通知所有的空闲线程*/ pthread_cond_broadcast(&(pool->queue_not_empty)); pthread_join(pool->threads[i], NULL); } threadpool_free(pool); return 0; }
//************************************************* int threadpool_destroy(threadpool_t *tp) { if (tp->shutdown) { log_err("already shutdown"); return -1; } tp->shutdown = 1; if (pthread_mutex_lock(&(tp->lock)) != 0) { log_err("lock in thread pool destroy"); return -1; } if (pthread_cond_broadcast(&(tp->condition)) != 0) { log_err("cond_broadcast in thread pool destroy"); return -1; } if (pthread_mutex_unlock(&(tp->lock)) != 0) { log_err("unlock in thread pool destroy"); return -1; } int i; int rcode = 0; for (i = 0; i < tp->thread_count; i++) { if (pthread_join(tp->threads[i], NULL) != 0) { log_err("thread join in thread pool destroy"); rcode = -1; } } if (!rcode) { pthread_mutex_destroy(&(tp->lock)); pthread_cond_destroy(&(tp->condition)); threadpool_free(tp); } return rcode; }
void demo3_thread_pool_test() { struct threadpool *pool; int arr[ARR_SIZE], i, ret, failed_count = 0; for (i = 0; i < ARR_SIZE; i++) { arr[i] = i; } if ((pool = threadpool_init(10)) == NULL) { printf("Error! Failed to create a thread pool struct.\n"); exit(EXIT_FAILURE); } for (i = 0; i < ARR_SIZE; i++) { if (i % 10000 == 0) { /* blocking. */ ret = threadpool_add_task(pool,slow_task,arr + i,1); } else { /* non blocking. */ ret = threadpool_add_task(pool,fast_task,arr + i,0); } if (ret == -1) { printf("An error had occurred while adding a task."); exit(EXIT_FAILURE); } if (ret == -2) { failed_count++; } } threadpool_free(pool,1); }
struct threadpool* threadpool_init(int num_of_threads) { struct threadpool *pool; int i; /* Create the thread pool struct. */ if ((pool = malloc(sizeof(struct threadpool))) == NULL) { perror("malloc: "); return NULL; } pool->stop_flag = 0; /* Init the mutex and cond vars. */ if (pthread_mutex_init(&(pool->free_tasks_mutex),NULL)) { perror("pthread_mutex_init: "); free(pool); return NULL; } if (pthread_mutex_init(&(pool->mutex),NULL)) { perror("pthread_mutex_init: "); free(pool); return NULL; } if (pthread_cond_init(&(pool->free_tasks_cond),NULL)) { perror("pthread_mutex_init: "); free(pool); return NULL; } if (pthread_cond_init(&(pool->cond),NULL)) { perror("pthread_mutex_init: "); free(pool); return NULL; } /* Init the jobs queue. */ threadpool_queue_init(&(pool->tasks_queue)); /* Init the free tasks queue. */ threadpool_queue_init(&(pool->free_tasks_queue)); /* Add all the free tasks to the free tasks queue. */ for (i = 0; i < THREAD_POOL_QUEUE_SIZE; i++) { threadpool_task_init((pool->tasks) + i); if (threadpool_queue_enqueue(&(pool->free_tasks_queue),(pool->tasks) + i)) { REPORT_ERROR("Failed to a task to the free tasks queue during initialization."); free(pool); return NULL; } } /* Create the thr_arr. */ if ((pool->thr_arr = malloc(sizeof(pthread_t) * num_of_threads)) == NULL) { perror("malloc: "); free(pool); return NULL; } /* Start the worker threads. */ for (pool->num_of_threads = 0; pool->num_of_threads < num_of_threads; (pool->num_of_threads)++) { if (pthread_create(&(pool->thr_arr[pool->num_of_threads]),NULL,worker_thr_routine,pool)) { perror("pthread_create:"); threadpool_free(pool,0); return NULL; } } return pool; }
int main(int argc, const char* argv[]) { if (argc <= 1) { printf("PLEASE ENTER THREAD NUMBER!\n"); return 0; } int nthreads=atoi(argv[1]); printf("Number of threads: %d\n", nthreads); init_pos(); double total = 0; int N = 3; int count; for (count = 1; count <= N; count ++) { struct timeval begin, end; double time_spent; gettimeofday(&begin, NULL); int n; for (n=0; n<NUM_TOPICS; n++) { // printf("Processing topic %d...\n", topics2011[n][0]); heap h_array[nthreads]; memset(h_array,0,sizeof(h_array)); struct threadpool *pool; pool = threadpool_init(nthreads); int i = 0; for (i=0; i<nthreads; i++) { struct arg_struct *args = malloc(sizeof *args); args->topic = n; args->startidx = i*(int)(ceil((double)NUM_DOCS / nthreads)); if ((i+1)*(int)(ceil((double)NUM_DOCS / nthreads)) > NUM_DOCS) { args->endidx = NUM_DOCS; } else { args->endidx = (i+1)*(int)(ceil((double)NUM_DOCS / nthreads)); } args->base = termindexes[nthreads-1][i]; heap h; h_array[i] = h; args->h = &h_array[i]; threadpool_add_task(pool,search,args,0); } threadpool_free(pool,1); heap h_merge; heap_create(&h_merge,0,NULL); float* min_key_merge; int* min_val_merge; for (i=0; i<nthreads; i++) { float* min_key; int* min_val; while(heap_delmin(&h_array[i], (void**)&min_key, (void**)&min_val)) { int size = heap_size(&h_merge); if ( size < TOP_K ) { heap_insert(&h_merge, min_key, min_val); } else { heap_min(&h_merge, (void**)&min_key_merge, (void**)&min_val_merge); if (*min_key_merge < *min_key) { heap_delmin(&h_merge, (void**)&min_key_merge, (void**)&min_val_merge); heap_insert(&h_merge, min_key, min_val); } } } heap_destroy(&h_array[i]); } int rank = TOP_K; while (heap_delmin(&h_merge, (void**)&min_key_merge, (void**)&min_val_merge)) { printf("MB%02d Q0 %ld %d %f Scan1_pos_multithread_intraquery\n", (n+1), tweetids[*min_val_merge], rank, *min_key_merge); rank--; } heap_destroy(&h_merge); } gettimeofday(&end, NULL); time_spent = (double)((end.tv_sec * 1000000 + end.tv_usec) - (begin.tv_sec * 1000000 + begin.tv_usec)); total = total + time_spent / 1000.0; } printf("Total time = %f ms\n", total/N); printf("Time per query = %f ms\n", (total/N)/NUM_TOPICS); }
void _join_main_thread() { pthread_join(main_thread, NULL); if(USE_THREAD_POOL){ threadpool_free(pool,1); } }