Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - julio1

#1
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:
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
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
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
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.
#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
Gracias por aportar una alternativa
#6
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.

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 C/C++ / Re: problema con fork
20 Enero 2019, 21:25 PM
Publiqué este comentario sin querer, si alguien hace el favor de eliminarlo...
#8
Programación C/C++ / Re: problema con fork
20 Enero 2019, 21:23 PM
Gracias por la ayuda creo que el codigo final quedari así:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main()
{
    printf("%d\n", getpid());
    int result = fork();
    switch (result)
    {
    case -1:
        perror("fork");
        break;
    case 0:
        printf("proceso hijo: %d\n", getpid());
        break;
    default:
        printf("proceso padre: %d\n", getpid());
        wait(NULL);

        break;
    }

    return 0;
}

#9
Programación C/C++ / problema con fork
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?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    printf("%d\n", getpid());
    int result = fork(), status;
    switch (result)
    {
    case -1:
        perror("fork");
        break;
    case 0:
        printf("proceso hijo: %d\n", getpid());
        break;
    default:
        printf("proceso padre: %d\n", getpid());
        break;
    }

    return 0;
}

La salida extraña es esta: