Last active
December 18, 2015 22:29
-
-
Save styxyang/5855263 to your computer and use it in GitHub Desktop.
It's not a good idea to pass a stack temporary variable(structure) to thread routine:
1. we don't know the execution sequence of created threads
2. the temporary variable(structure) may get cleared before the sub threads access it
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* definition of thread argument passed to pool wrapper*/ | |
typedef struct { | |
thread_pool *pool; | |
uint64_t id; | |
} thread_argument; | |
////////////////////////////////////////////////////////////// | |
// thread_pool_wrapper: thread start routine waiting for tasks | |
// to execute | |
///////////////////////////////////////////////////////////// | |
/* version 1: use temporary variable in main thread stack */ | |
void *thread_pool_wrapper(void *arg) | |
{ | |
thread_argument *ta = (thread_argument *)arg; | |
thread_pool *pool = ta->pool; | |
uint64_t id = ta->id; | |
} | |
/* version 2: use global counter `nthread' and `xadd' instruction */ | |
void *thread_pool_wrapper(void *arg) | |
{ | |
uint64_t id = __sync_fetch_and_add(&nthread, 1); | |
} | |
////////////////////////////////////////////////////////////// | |
// thread_pool_init: create workers with thread_pool_wrapper | |
// with thread info stored in array | |
///////////////////////////////////////////////////////////// | |
void thread_pool_init(thread_pool *pool) | |
{ | |
uint64_t i; | |
pool->bitmap = 0L; | |
pool->tear_down = 0; | |
pthread_mutex_init(&mutex, NULL); | |
pthread_mutex_init(&pool_mutex, NULL); | |
pthread_mutex_init(&io_mutex, NULL); | |
pthread_cond_init(&cond, NULL); | |
pthread_mutex_lock(&mutex); | |
memset(&pool->tasks, 0, MAX_WORKER * sizeof(worker_task)); | |
for (i = 0; i < WORKER_ENABLE; ++i) | |
{ | |
/* version 1: pass a stack structure to wapper */ | |
thread_argument ta = { | |
.pool = pool, | |
.id = i | |
}; | |
pthread_create(&(pool->tasks[i].tid), NULL, thread_pool_wrapper, &ta); | |
/* version 2: pass only pool argument (actually can be nothing) | |
and leave id to be determined by `xadd' */ | |
pthread_create(&(pool->tasks[i].tid), NULL, thread_pool_wrapper, pool); | |
dprintf(INFO, "pthread_create: %x\n", pool->tasks[i].tid); | |
} | |
pthread_mutex_unlock(&mutex); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment