我发送sturct dataBlock
到我的主题,其中包含a pointer
到同一个listRoot(适用于所有主题),int indexInForLoop
和int listSize
;列表中的节点有一个int值,要处理的灰烬和一个int工作者,它是nrOfListElements%nrOfWorkers(Threads)。但不知怎的,我发送到每个线程的结构是相同的,但它不应该每个都应该有一个不同的int变量与indexFromForLoop。我做错了什么?
终端输出:
node #1 worker: 1 value: 86
node #2 worker: 0 value: 77
node #3 worker: 1 value: 15
node #4 worker: 0 value: 93
node #5 worker: 1 value: 35
? List got populated
workersInput: 2
in for, ret= 0
in for, ret= 0
* Thread start: id: 3067579200^
forID_ 1
->val: 86
valid for sqrt
* Thread start: id: 3075971904^
forID_ 1
->val: 86
valid for sqrt
代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <math.h>
#define workTime 5
#define workersLimitNr 3
struct dataBlock{
struct node *root;
int listSize;
int forIndex;
};
struct node { // std linked list node
int value;
int worker;
struct node *next;
};
int slots = 0; // only 3 threads are allowed to access the list
int availableCheck(){ // check if thread can acces the list
if(slots < 3) return 0;
else return -1;
}
pthread_mutex_t mutp = PTHREAD_MUTEX_INITIALIZER; //condvar mutex
pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; //condvar
void * worker( void *data ){
struct dataBlock *inData = (struct dataBlock *) data;
struct node *root = inData->root;
int listSize = inData->listSize;
int forIndex = inData ->forIndex;
printf( "* Thread start: ^\n");
pthread_mutex_lock( &mutp );
if(availableCheck() < 0){
printf( " ^^^ List not available yet... \n" );
pthread_cond_wait( &condvar, &mutp );
}
struct node *it = root;
printf("forID_ %d \n", forIndex);
while(it->next != NULL){
if(forIndex == it->worker){
printf("valid for sqrt \n");
if(it->value > 2){
sqrt(it->value);
break;
}
}
it = it->next;
printf("->val: %d \n", it->value);
}
pthread_cond_signal( &condvar ); //
pthread_mutex_unlock( &mutp );
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);
}
printf("? List got populated\n");
// Create all threads to parse the link list
int ret;
printf("workersInput: %d\n",nrWorkers);
pthread_t w_thread;
pthread_t* w_threads = malloc(nrWorkers * sizeof(w_thread));
struct dataBlock *data = malloc(sizeof(struct dataBlock));
data->root = root;
data->listSize = listSize;
for( i=0; i < nrWorkers; i++ ){
data->forIndex = i;
ret = pthread_create ( &w_threads[i], NULL, worker, (void *) data );
if( ret ) {
perror("Thread creation fail");
exit(2);
}
printf("in for, ret= %d\n",ret);
}
for ( i = 0; i < nrWorkers; i++){
pthread_join(w_threads[i],NULL);
}
free(root);
free(iterator);
return 0;
}
编辑:我使用了pthread_self(),我确认存在不同的威胁
答案 0 :(得分:1)
使用
data->forIndex = i;
你覆盖以前的值。因为你只有一个dataBlock
,每个线程都会看到同一个地方。因为创建一个线程不意味着“在执行循环中的下一个语句之前启动它”,所以每个线程看到的值都是纯粹的运气。
您必须为每个帖子分配一个dataBlock
,并将每个dataBLock
仅提供给一个帖子。