неправильный вектор обработки результатов <int>с потоками - PullRequest
0 голосов
/ 24 января 2012
EDIT: Question closed.

Рекомендуемая мощность элементов


int mypow(int n) { return n * n; }

transform(datos->origen->begin(),datos->origen->end(),datos->cuads->begin(),mypow);

Я пытаюсь получить сумму, минимальное и среднее значение по вектору int одновременно. Я использую Ubuntu 11.10, Codelite и G ++ с phtreads.

Я заполняю вектор и создаю поток для каждой задачи. Но я получил неверный результат.

Я думаю, что код в порядке, но на самом деле нет, и я не знаю почему.

Заполнив вектор int 10-ю целыми числами, я получил следующее выполнение:

Sum: 110
Min: 2
original container length:10
2
4
6
... to 20

pow container lenght:20
0
0
0
... 10 zeros

4  ----> true result after pow elements
16
36
64
... rest of elements

Main thread ended

Заранее спасибо

код:

#include <iostream>
#include <vector>

#include <pthread.h>

using std::cout;
using std::cin;     // C++ uses
using std::endl;
using std::vector;


// struct to store results
typedef struct
{
int suma;
int min;
vector<int>* origen;
vector<int>* cuads;
}tdata;


// mutex
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;


// Adition funct
void *suma(void* ptr)
{

// lock mutex
pthread_mutex_lock( &mutex1 );

tdata* datos = reinterpret_cast<tdata*>(ptr);

// iterator
vector<int>::const_iterator it1 = datos->origen->begin();

while( it1 != datos->origen->end() )
{
    datos->suma += *it1;    
    it1++;
}

pthread_mutex_unlock( &mutex1 );

 return 0;
}

// minimun function
void* min(void *ptr)
{ 

pthread_mutex_lock( &mutex1 );

tdata* datos = reinterpret_cast<tdata*>(ptr);

datos->min = datos->origen->at(0); // inicializo el menor

vector<int>::const_iterator it2 = datos->origen->begin();

while( it2 != datos->origen->end())
{   
    if ( (*it2) < datos->min )
        datos->min = (*it2);

        it2++;  
}

pthread_mutex_unlock( &mutex1 );
    return 0;
 }

// pow function. Dinamically alloc vector and fill it
void* cuadrados( void* ptr)
 {

pthread_mutex_lock( &mutex1 );

tdata* datos = reinterpret_cast<tdata*>(ptr);

// Error int tan = static_cast<int>(datos->origen->size());

datos->cuads = new vector<int>();  // Error new vector<int>(tan);               

vector<int>::const_iterator it3 = datos->origen->begin();

while( it3 != datos->origen->end() )
{       
    int n = (*it3) * (*it3);
    datos->cuads->push_back(n);

    it3++;  
}   
pthread_mutex_unlock( &mutex1 );
  return 0;
 }



int main(int argc, char **argv)
{

#define MAXHILOS 3      // nº de hilos
#define MAXNUMS 10      // cantidad de numeros

vector<int> enteros;    // vector de enteros            

pthread_t hilos[MAXHILOS];  // vector de hilos


    // fill origin vector
    for ( int i = 0; i < MAXNUMS; i++)
            enteros.push_back((i+1)*2);


    // init target structure
    tdata t = {0};

    // point to origin vector
    t.origen = &enteros;

        // thread creation                                  
        pthread_create(&hilos[0],NULL,suma,&t);         
        pthread_create(&hilos[1],NULL,min,&t);
        pthread_create(&hilos[2],NULL,cuadrados,&t);

        // wait until all threads ends
        pthread_join(hilos[0], NULL);
        pthread_join(hilos[1], NULL);
        pthread_join(hilos[2], NULL);


        // show results         
        cout << "Sum: " << t.suma << endl
             << "Min: " << t.min << endl;

        cout << "original vector length:" << enteros.size() << endl;

        vector<int>::const_iterator ent = enteros.begin();

        while( ent != enteros.end() )
        {   
            cout << (*ent) << endl;                             
            ent++;  
        }

        cout << "pow vector length:" << t.cuads->size() << endl;            


        vector<int>::const_iterator cuadr =t.cuads->begin();

        while( cuadr != t.cuads->end() )
        {   
            cout << (*cuadr) << endl;                               
            cuadr++;    
        }


        //delete[] t.cuads;         
        cout << "Main thread ended" << endl;

cin.get();
return 0;
} 
EDIT: Yes, the trouble was creating the vector with fixed size.
Thanks to all. 

Ответы [ 2 ]

2 голосов
/ 24 января 2012

Я считаю, что проблема в десяти нулях в начале tdata.cuads vector.Это вызвано:

// This allocates a new vector with 'tan' number of ints
// and initialises them to zero.
datos->cuads = new vector<int>(tan);                

// This loops appends new elements to the 'cuads' vector,
// after the ten zeros.
while( it3 != datos->origen->end() )
{       
    int n = (*it3) * (*it3);
    datos->cuads->push_back(n);

    it3++;  
}   

Чтобы исправить это, либо объявите создание cuads без начального размера:

datos->cuads = new vector<int>();                

while( it3 != datos->origen->end() )
{       
    int n = (*it3) * (*it3);
    datos->cuads->push_back(n);

    it3++;  
}   

, либо используйте operator[] для заполнения cuads:

datos->cuads = new vector<int>(tan);                

size_t i = 0;
while( it3 != datos->origen->end() )
{       
    int n = (*it3) * (*it3);
    *(datos->cuads)[i++] = n;
    it3++;  
}   

Несколько других незначительных точек:

  • typedef не требуется при определении struct в C ++, просто struct tdata { ... };.
  • youможно использовать std::accumulate() для вычисления суммы контейнера и std::min_element() для поиска минимального значения контейнера.

Например:

dataos->suma = std::accumulate(dataos->origen->begin(), dataos->origen->end(), 0);
dataos->min  = *std::min_element(dataos->origen->begin(), dataos->origen->end());
2 голосов
/ 24 января 2012

Это никак не связано с потоками.Вы создали cuads с помощью «конструктора заливки по умолчанию», который заполняет его таким количеством элементов, созданных по умолчанию, как его аргумент.В этом случае вы запросили 10 (размер origen), а построенные по умолчанию целые числа равны нулю, поэтому у вас есть вектор, содержащий 10 нулей.Затем вы поместили свои значения мощности в конец, создав 20 элементов.

Просто используйте обычный конструктор vector<T> по умолчанию для cuads, и ошибка исчезнет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...