【发布时间】:2012-12-27 14:04:38
【问题描述】:
我想确保我的 sempahore 做我期望做的事情,但我无法将它带到一个或多个线程等待的状态。我一次只需要 3 个线程就可以处理链表。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <math.h>
#include <semaphore.h>
struct dataBlock{
struct node *root;
int listSize;
int forIndex;
};
struct node { // std linked list node
int value;
int worker;
struct node *next;
};
int limit = 5;
sem_t sem;
pthread_mutex_t mutp = PTHREAD_MUTEX_INITIALIZER; // mutex
pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; //condvar
void *deleteDoneNodes(struct node *n){
struct node *root = n;
struct node *it = root;
struct node *prev = NULL;
do{
if(it->value == 1){
struct node *next = it->next;
if (prev != NULL) {
prev->next = next;
}
if (it == root) {
root = next;
}
free(it);
it = next;
}
else {
prev = it;
it = it->next;
}
}while(it != NULL);
return root;
}
void * worker( void *data ){
//get list
int wFlag;
struct dataBlock *inData = ( struct dataBlock * ) data;
struct node *root = inData->root;
int forIndex = inData ->forIndex;
free(data);
while(1){
if( sem_wait( &sem ) != 0 ){
printf( " > waiting... \n" );
}
// pthread_mutex_lock( &mutp );
struct node *it = root;
do{
if( forIndex == it->worker ){
if( it->value > 2 ){
while( it->value != 1 )
it->value = sqrt(it->value);
}
}
else{
// printf("Not sqrt-able node %d\n",it->value);
}
it = it->next;
}while(it != NULL);
// pthread_cond_signal( &condvar );
// pthread_mutex_unlock( &mutp );
sem_post(&sem);
// sleep(100); // "create" concurrancy envi.
pthread_exit(0);
}
return NULL;
}
int main( int argc, char *argv[] ){
if ( argc != 3 ){
printf( "Programm must be called with \n NR of elements and NR of workers! \n " );
exit( 1 );
}
int i;
struct node *root;
struct node *iterator;
//prepare list for task
int listSize = atoi(argv[1]);
int nrWorkers = atoi(argv[2]);
root = malloc(sizeof( struct node) );
root->value = rand() % 100;
root->worker = 0;
iterator = root;
for( i=1; i<listSize; i++ ){
iterator->next = malloc(sizeof(struct node));
iterator = iterator->next;
iterator->value = rand() % 100;
iterator->worker = i % nrWorkers;
printf("node #%d worker: %d value: %d\n", i, iterator->worker,iterator->value);
}
iterator->next = NULL;
printf("? List got populated\n");
// init semaphore > keeps max 3 threads working over the list
if( sem_init(&sem,0,3) < 0){
perror("semaphore initilization");
exit(0);
}
// Create all threads to parse the link list
int ret;
pthread_mutex_init(&mutp,NULL);
pthread_t w_thread;
pthread_t* w_threads = malloc(nrWorkers * sizeof(w_thread));
for( i=0; i < nrWorkers; i++ ){
struct dataBlock *data = malloc(sizeof(struct dataBlock));
data->root = root;
data->listSize = listSize;
data->forIndex = i;
ret = pthread_create ( &w_threads[i], NULL, worker, (void *) data );
if( ret ) {
perror("Thread creation fail");
exit(2);
}
}
deleteDoneNodes( root );
int join;
for ( i = 0; i < nrWorkers; i++ ){
join = pthread_join(w_threads[i],NULL);
}
iterator = root;
for ( i = 0; i < listSize; i++){
printf("val: %d worker: %d _ \n", iterator->value, iterator->worker);
iterator = iterator->next;
}
free(root);
free(iterator);
sem_destroy(&sem);
return 0;
}
终端~> ./s 16 16
node #1 worker: 1 value: 86
node #2 worker: 2 value: 77
node #3 worker: 3 value: 15
node #4 worker: 4 value: 93
node #5 worker: 5 value: 35
node #6 worker: 6 value: 86
node #7 worker: 7 value: 92
node #8 worker: 8 value: 49
node #9 worker: 9 value: 21
node #10 worker: 10 value: 62
node #11 worker: 11 value: 27
node #12 worker: 12 value: 90
node #13 worker: 13 value: 59
node #14 worker: 14 value: 63
node #15 worker: 15 value: 26
? List got populated
val: 1 worker: 0 _
val: 1 worker: 1 _
val: 1 worker: 2 _
val: 1 worker: 3 _
val: 1 worker: 4 _
val: 1 worker: 5 _
val: 1 worker: 6 _
val: 1 worker: 7 _
val: 1 worker: 8 _
val: 1 worker: 9 _
val: 1 worker: 10 _
val: 1 worker: 11 _
val: 1 worker: 12 _
val: 1 worker: 13 _
val: 1 worker: 14 _
val: 1 worker: 15 _
【问题讨论】:
-
您期望发生但没有发生的事情是什么?您是否尝试将评论的
sleep()inside 放在sem_wait()/sem_post()块中,而不是放在外面? -
不要动态地重新初始化你的互斥锁。静态初始化是完全足够的。
w_thread有什么用?是否只是计算pthread_t类型的sizeof?所有这一切都表明,您首先应该自己检查代码,提出一个具体问题,将其归结为可重现的东西,然后再回来。 SO 不适用于代码审查。 -
@flavo 我为什么要那样做?!在做任何事情之前,我需要线程等待
-
你说“我不能把它带到一个或多个线程等待的状态”,所以我建议移动
sleep以强制一些线程等待信号量。但是,正如@Jens 和我已经说过的那样,请尝试澄清您的要求。 -
@Flavio “我一次只需要 3 个线程就可以处理链表。”意思是超过 3 个线程,3 个应该能够访问列表...