Помогите использовать семфоры и темы - PullRequest
0 голосов
/ 06 июля 2010

Я использую библиотеку pthread для имитации многопоточного буфера.Я также использую семафоры в качестве решения для доступа к переменным критической секции по одной.

Основная проблема заключается в том, что производитель заполняет весь буфер, а потребитель затем очищает весь буфер.Этот код правильный?Я предполагал, что производство и потребление произойдут до того, как буфер будет заполнен или пуст.

Вот мой код, и любые комментарии очень помогут, и да, это для класса.

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

void *Producer(void *threadid) 
{
   long tid;
   tid = (long)threadid;

   while (c < Cycles)  //While stuff to buffer
   {                        
        pthread_mutex_lock(&lock);           
        while(size == BUFFER_SIZE)  
        {
           pthread_cond_wait(&cond, &lock);    
        }
     buffer [full] = rand();
     data << size+1 << ". Produce: " << buffer[full] << endl;
     printBuffer();
     full = (full + 1) % BUFFER_SIZE;
     size++;
     pthread_cond_signal(&cond1);
     pthread_mutex_unlock(&lock);
     c++;
   }
   pthread_exit(NULL);
}

Вы также можете скачать весь код или просмотреть файл журнала ...

загрузить main.cpp просмотреть файл журнала на funkohland.com / Pthreads / log.txt

Ответы [ 3 ]

1 голос
/ 06 июля 2010

Это хорошо известная проблема с мьютексами.Mutex - это дорогая операция, которая требует много циклов.Когда вы разблокируете мьютекс, у другого потока будет крошечная возможность выйти из своей блокировки и получить блокировку.По сути, вам нужно тратить меньше времени на мьютекс, чтобы дать возможность другому потоку работать.По сути, вам нужно выбрать часть кода, для которой фактически необходим мьютекс, а затем быстро заблокировать мьютекс, сделать все, что вам нужно сделать с этой переменной (и ничего более), а затем разблокировать ее.

0 голосов
/ 06 июля 2010

В то время как ответ Гоза является причиной, возможное решение состоит в том, чтобы уступить планировщику за пределами мьютекса, используя usleep(1) или sched_yield() / Sleep(0) (в зависимости от ОС).

Кроме того, так какваш продюсер использует rand (), это мало что меняет, но если он использовал трудоемкий ввод-вывод или продвинутые алгоритмы для создания новых объектов, которые нужно вставить, правильный подход заключается в том, чтобы выполнить фактическое производство без преобразования в локальный буфер,затем только мьютекс, вставляющий вновь созданный объект в очередь.

0 голосов
/ 06 июля 2010

Для начала вы должны убедиться, что доступ к общим переменным 'c' и 'size' осуществляется внутри критического раздела.То есть между блокировкой и разблокировкой звонков.В настоящее время вы свободно обращаетесь к 'c' и иногда к 'size' без надлежащей блокировки.

...