我很好奇我做错了什么,因为我的void *DeleteDoneNodes(node * n)
没有做任何事情,没有错误但没有更好的输出,所以任何人都可以帮助我找到问题的根源谢谢你。
场景:cmd行./s m n
m
列表中的n
个节点数,node->value == 1
workingThreads的数量应该用#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <math.h>
#include <semaphore.h>
#define finishedNodes 5
#define workersLimitNr 3
int workingThreads = 0;
sem_t sem;
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; // mutex
pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; //condvar
void *deleteDoneNodes(struct node *n){ // T H I S I S T H E F U N C
struct node *root = n;
struct node *it;
it = root;
do{
if(it->value == 1){
struct node *tmp;
printf("DELETING: %d > %d\n", it->value, it->worker );
root = root->next;
tmp = it;
it = it->next;
free(tmp);
}
else
it = it->next;
}while(it != NULL);
return NULL;
}
void * worker( void *data ){
struct dataBlock *inData = (struct dataBlock *) data;
struct node *root = inData->root;
int forIndex = inData ->forIndex;
free(data);
printf( "* Thread id: %lu forID: %d workerNode: \n",pthread_self(),forIndex);
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 );
do{
if(forIndex == it->worker){
printf("valid for sqrt forIndex %d == it->worker %d\n",forIndex, it->worker );
if(it->value > 2){
while(it->value != 1)
it->value = sqrt(it->value);
// it->value = it->value - 1;
}
}
it = it->next;
}while(it != NULL);
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);
}
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 );
// printf( ">>>> %d\n", root->value );
for ( i = 0; i < nrWorkers; i++ ){
pthread_join(w_threads[i],NULL);
}
// for ( i = 0; i < nrWorkers; i++){
// free(w_threads);
// }
iterator = root;
for ( i = 0; i < listSize; i++){
printf("val: %d worker: %d _ ", iterator->value, iterator->worker);
iterator = iterator->next;
}
free(root);
free(iterator);
return 0;
}
删除每个节点,但它没有做任何事情......
代码:
{{1}}
PS:它编译/工作错误/无警告 - 也用valgrind测试。
答案 0 :(得分:1)
这是一个替代版本
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;
}
主要变化是:
next
指针。没有它,它将继续指向释放的记忆。root
的逻辑。只有在我们免费root
root
中传达可能的变化。如果我们从列表中删除root(aka head)项,则需要将其传递给调用者。我通过返回root
而不是NULL