Browse Source

feat: free pool memory after join process

master
Dnomd343 1 year ago
parent
commit
a1a769239b
  1. 10
      main.c
  2. 30
      tiny_pool.c

10
main.c

@ -14,9 +14,10 @@ void demo_fun(void *i) {
int main() { int main() {
pool_t *pool = tiny_pool_create(2); // pool_t *pool = tiny_pool_create(2);
pool_t *pool = tiny_pool_create(4);
int dat[] = {1, 2, 3, 4, 5, 6, 7, 8}; int dat[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
tiny_pool_submit(pool, demo_fun, (void*)&dat[0]); tiny_pool_submit(pool, demo_fun, (void*)&dat[0]);
tiny_pool_submit(pool, demo_fun, (void*)&dat[1]); tiny_pool_submit(pool, demo_fun, (void*)&dat[1]);
@ -31,11 +32,16 @@ int main() {
tiny_pool_submit(pool, demo_fun, (void*)&dat[2]); tiny_pool_submit(pool, demo_fun, (void*)&dat[2]);
tiny_pool_submit(pool, demo_fun, (void*)&dat[3]); tiny_pool_submit(pool, demo_fun, (void*)&dat[3]);
tiny_pool_submit(pool, demo_fun, (void*)&dat[4]); tiny_pool_submit(pool, demo_fun, (void*)&dat[4]);
tiny_pool_submit(pool, demo_fun, (void*)&dat[5]);
tiny_pool_submit(pool, demo_fun, (void*)&dat[6]);
printf("+ main: sleep 8s\n"); printf("+ main: sleep 8s\n");
sleep(6); sleep(6);
printf("+ main: wake up\n"); printf("+ main: wake up\n");
tiny_pool_submit(pool, demo_fun, (void*)&dat[7]);
tiny_pool_submit(pool, demo_fun, (void*)&dat[8]);
printf("+ main: pool joining\n"); printf("+ main: pool joining\n");
tiny_pool_join(pool); tiny_pool_join(pool);
printf("+ main: pool join complete\n"); printf("+ main: pool join complete\n");

30
tiny_pool.c

@ -56,7 +56,7 @@ pool_t* tiny_pool_create(uint32_t size) {
} }
void task_queue_push(pool_t *pool, task_t *task) { void task_queue_push(pool_t *pool, task_t *task) {
printf("push new task\n"); printf("push new task %d\n", *(int*)task->arg);
if (pool->task_queue_rear == NULL) { // task queue is empty if (pool->task_queue_rear == NULL) { // task queue is empty
pool->task_queue_front = task; pool->task_queue_front = task;
pool->task_queue_rear = task; // init task queue with one element pool->task_queue_rear = task; // init task queue with one element
@ -69,12 +69,12 @@ void task_queue_push(pool_t *pool, task_t *task) {
} }
task_t* task_queue_pop(pool_t *pool) { // pop one task with blocking wait task_t* task_queue_pop(pool_t *pool) { // pop one task with blocking wait
printf("%lu -> pop one task\n", pthread_self()); printf("%lu -> start pop task\n", pthread_self());
/// wait until task queue not empty /// wait until task queue not empty
pthread_mutex_lock(&pool->mutex); // lock pool struct pthread_mutex_lock(&pool->mutex); // lock pool struct
while (pool->task_queue_front == NULL) { // loop until task queue not empty while (pool->task_queue_front == NULL) { // loop until task queue not empty
printf("%lu -> pop start wait\n", pthread_self()); printf("%lu -> pop wait\n", pthread_self());
pthread_cond_wait(&pool->task_queue_not_empty, &pool->mutex); // wait new task added pthread_cond_wait(&pool->task_queue_not_empty, &pool->mutex); // wait new task added
printf("%lu -> pop exit wait\n", pthread_self()); printf("%lu -> pop exit wait\n", pthread_self());
if (pool->status == EXITING) { if (pool->status == EXITING) {
@ -82,7 +82,7 @@ task_t* task_queue_pop(pool_t *pool) { // pop one task with blocking wait
pthread_exit(NULL); // sub thread exit at EXITING stage pthread_exit(NULL); // sub thread exit at EXITING stage
} }
} }
printf("%lu -> pop new task\n", pthread_self()); printf("%lu -> pop new task %d\n", pthread_self(), *(int*)pool->task_queue_front->arg);
/// pop first task from queue /// pop first task from queue
bool empty_flag = false; bool empty_flag = false;
@ -99,6 +99,7 @@ task_t* task_queue_pop(pool_t *pool) { // pop one task with blocking wait
/// send signal to active blocking thread /// send signal to active blocking thread
if (empty_flag) { // send signal after mutex unlocked if (empty_flag) { // send signal after mutex unlocked
printf("signal -> task queue empty\n");
pthread_cond_signal(&pool->task_queue_empty); // active pool join thread pthread_cond_signal(&pool->task_queue_empty); // active pool join thread
} }
return front; // success pop one task return front; // success pop one task
@ -208,7 +209,6 @@ bool tiny_pool_join(pool_t *pool) {
} }
printf("task queue empty\n"); printf("task queue empty\n");
pool->status = EXITING; pool->status = EXITING;
printf("pool status -> EXITING\n"); printf("pool status -> EXITING\n");
@ -220,12 +220,6 @@ bool tiny_pool_join(pool_t *pool) {
pthread_mutex_unlock(&pool->mutex); // prevent other functions blocking waiting pthread_mutex_unlock(&pool->mutex); // prevent other functions blocking waiting
printf("unlock mutex and send broadcast\n");
// pthread_cond_broadcast(&pool->task_queue_not_empty); // send broadcast to trigger idle threads
// TODO: signal broadcast and wait all thread exit
printf("start sub threads joining\n"); printf("start sub threads joining\n");
for (uint32_t i = 0; i < pool->thread_num; ++i) { for (uint32_t i = 0; i < pool->thread_num; ++i) {
pthread_cond_broadcast(&pool->task_queue_not_empty); // trigger idle threads pthread_cond_broadcast(&pool->task_queue_not_empty); // trigger idle threads
@ -234,5 +228,19 @@ bool tiny_pool_join(pool_t *pool) {
} }
printf("sub threads join complete\n"); printf("sub threads join complete\n");
// TODO: free resource
printf("start free pool resource\n");
pthread_cond_destroy(&pool->without_busy_thread);
pthread_cond_destroy(&pool->task_queue_not_empty);
pthread_cond_destroy(&pool->task_queue_empty);
pthread_mutex_destroy(&pool->mutex);
free(pool->threads);
free(pool);
printf("free pool resource complete\n");
return true; return true;
} }

Loading…
Cancel
Save