elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)


  Mostrar Mensajes
Páginas: [1]
1  Programación / Programación C/C++ / Re: condicion de carrera c++ threads en: 4 Abril 2019, 00:00 am
He solucionado el problema de la condición de carrera, helgrind ya no se queja, la culpa la tenía el método size en la línea while(num_producers_working != 0 || products.size() > 0)
la solución más simple pasa por meter a size dentro de una sección crítica:
Código:
size_t stack_size(const stack<int> &obj ){
    lock_guard<mutex> guardian(xmutex);
    return obj.size();

}
Modificando así la línea anterior ahora: while(num_producers_working != 0 || stack_size(products) > 0)
2  Programación / Programación C/C++ / Re: condicion de carrera c++ threads en: 3 Abril 2019, 21:36 pm
Gracias, lo miro ahora. Lo que dijiste de la funcion print en el visual studio te da error al compilar o te compila sin problemas?
3  Programación / Programación C/C++ / Re: condicion de carrera c++ threads en: 3 Abril 2019, 21:18 pm
Con respecto a la primera estoy de acuerdo contigo, la verdad es que no me había fijado, es curioso porque no estoy en un compilador raro estoy usando g++ en su versión 7, y porque g++ permitirá esto? Si mal no recuerdo al tomar una referencia el parametro de una función se puede llamar como un rvalue si el parámetro es const.
Y yendo a la segunda nunca había oído hablar de un wakeup espurio.
4  Programación / Programación C/C++ / condicion de carrera c++ threads en: 3 Abril 2019, 18:35 pm
Estoy mirando el problema del productor/consumidor con threads en c+11. Pues bien, el siguiente código me da un problema con helgrind detecta una condicion de carrera y debuggeando un poco creo que el problema esta en la funcion consumer pero no estoy seguro y no se como resolverlo.
Código:
#include <iostream>
#include <sstream>
#include <vector>
#include <stack>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <chrono>
using namespace std;
 
// print function for "thread safe" printing using a stringstream
void print(ostream& s) { cout << s.rdbuf(); cout.flush(); s.clear(); }
 
const int num_producers = 5;
const int num_consumers = 10;
const int producer_delay_to_produce = 10;   // in miliseconds
const int consumer_delay_to_consume = 30;   // in miliseconds
const int consumer_max_wait_time = 200;     // in miliseconds - max time that a consumer can wait for a product to be produced.
const int max_production = 10;              // When producers has produced this quantity they will stop to produce
const int max_products = 10;                // Maximum number of products that can be stored
 
atomic<int> num_producers_working(0);       // When there's no producer working the consumers will stop, and the program will stop.
stack<int> products;                        // The products stack, here we will store our products
mutex xmutex;                               // Our mutex, without this mutex our program will cry
 
condition_variable is_not_full;             // to indicate that our stack is not full between the thread operations
condition_variable is_not_empty;            // to indicate that our stack is not empty between the thread operations
 

void produce(int producer_id)
{
        unique_lock<mutex> lock(xmutex);
        int product;
 
        is_not_full.wait(lock, [] { return products.size() != max_products; });
        product = products.size();
        products.push(product);
 
        print(stringstream() << "Producer " << producer_id << " produced " << product << "\n");
        is_not_empty.notify_one();
}
 
//      Consume function, consumer_id will consume a product
void consume(int consumer_id)
{
        unique_lock<mutex> lock(xmutex);
        int product;
 
        if(is_not_empty.wait_for(lock, chrono::milliseconds(consumer_max_wait_time),
                [] { return products.size() > 0; }))
        {
                product = products.top();
                products.pop();
 
                print(stringstream() << "Consumer " << consumer_id << " consumed " << product << "\n");
                is_not_full.notify_one();
        }
}
 
void producer(int id)
{
        ++num_producers_working;
        for(int i = 0; i < max_production; ++i)
        {
                produce(id);
                this_thread::sleep_for(chrono::milliseconds(producer_delay_to_produce));
        }
 
        print(stringstream() << "Producer " << id << " has exited\n");
        --num_producers_working;
}
 
void consumer(int id)
{
        // Wait until there is any producer working
        while(num_producers_working == 0) this_thread::yield();
 
        while(num_producers_working != 0 || products.size() > 0)
        {
                consume(id);
                this_thread::sleep_for(chrono::milliseconds(consumer_delay_to_consume));
        }
 
        print(stringstream() << "Consumer " << id << " has exited\n");
}
 
int main()
{
        vector<thread> producers_and_consumers;
 
        // Create producers
        for(int i = 0; i < num_producers; ++i)
                producers_and_consumers.push_back(thread(producer, i));
 
        // Create consumers
        for(int i = 0; i < num_consumers; ++i)
                producers_and_consumers.push_back(thread(consumer, i));
 
        // Wait for consumers and producers to finish
        for(auto& t : producers_and_consumers)
                t.join();
}
5  Programación / Programación C/C++ / Re: Programa que solo acepte números en: 4 Febrero 2019, 19:19 pm
Gracias por aportar una alternativa
6  Programación / Programación C/C++ / Programa que solo acepte números en: 3 Febrero 2019, 11:48 am
Estoy intentando hacer una función que pida un numero del 0 al 9 al usuario y que sea robusta. He estado mirando códigos para guiarme y la mayoría fallan al encontrarse con alguna de estas situaciones, normalmente debido al uso de cin:
1- Si el usuario introduce espacios antes del numero o después, la entrada es válida
2- Si se pulsa control+z (eof en windows) se produce un ciclo infinito o la entrada se da como válida
3- Si el usuario tipeo 2ff la entrada resulta válida
4- La entrada se queda esperando a que tecleemos algo por culpa de algún salto de línea
He hecho el siguiente código, creo que soluciona los problemas comentados anteriormente. Me gustaría saber su opinión y si creen en algún caso dónde podría fallar o si puedo mejorarlo.

Código:
int pedir_numero()
{

    string data = "";
    while (true)
    {

        cout << "Introduce una opcion: ";
        if (!getline(cin, data))
        {
            return -1;
        }
        if (data.length() != 1 || isspace(data[0]))
        {
            cerr << "Numero invalido, vuelve a intentarlo!" << endl;
            continue;
        }
        try
        {
            return stoi(data);
        }
        catch (const exception &e)
        {
            cerr << "Numero invalido, vuelve a intentarlo!" << endl;
        }
    }
}
7  Programación / Programación C/C++ / Re: problema con fork en: 20 Enero 2019, 21:25 pm
Publiqué este comentario sin querer, si alguien hace el favor de eliminarlo...
8  Programación / Programación C/C++ / Re: problema con fork en: 20 Enero 2019, 21:23 pm
Gracias por la ayuda creo que el codigo final quedari así:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/wait.h>
  5.  
  6. int main()
  7. {
  8.    printf("%d\n", getpid());
  9.    int result = fork();
  10.    switch (result)
  11.    {
  12.    case -1:
  13.        perror("fork");
  14.        break;
  15.    case 0:
  16.        printf("proceso hijo: %d\n", getpid());
  17.        break;
  18.    default:
  19.        printf("proceso padre: %d\n", getpid());
  20.        wait(NULL);
  21.  
  22.        break;
  23.    }
  24.  
  25.    return 0;
  26. }
9  Programación / Programación C/C++ / problema con fork en: 20 Enero 2019, 16:59 pm
Estoy usando fork en ubuntu, entiendo que el proceso padre es el proceso principal y que el proceso hijo es el secundario. Tengo un problema con este codigo, que muestra una salida extraña algunas veces, porque sucede esto?
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4.  
  5. int main()
  6. {
  7.    printf("%d\n", getpid());
  8.    int result = fork(), status;
  9.    switch (result)
  10.    {
  11.    case -1:
  12.        perror("fork");
  13.        break;
  14.    case 0:
  15.        printf("proceso hijo: %d\n", getpid());
  16.        break;
  17.    default:
  18.        printf("proceso padre: %d\n", getpid());
  19.        break;
  20.    }
  21.  
  22.    return 0;
  23. }
  24.  
La salida extraña es esta:
Páginas: [1]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines