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ú

Temas - julio1

#1
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();
}
#2
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;
       }
   }
}
#3
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: