Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.11.2015, 16:42   #1
WolfEater
Пользователь
 
Регистрация: 15.02.2015
Сообщений: 21
По умолчанию Программа на Си "Синхронизация потоков"

Здравствуйте. Помогите, пожалуйста, решить проблему.
Решите классическую проблему «поставщик – потребитель» с использованием средств синхронизации.
Постановка задачи:
Один поток производит данные, другой поток их потребляет. В промежуток времени между изготовлением и потреблением данные хранятся в буфере.

Исходные данные:
Данные хранятся в циклическом буфере. Циклический буфер описывается некоторой областью памяти, указателем начала данных и указателем конца данных. Поток-поставщик записывает данные в конец буфера, поток-потребитель считывает их с начала буфера. После записи или чтения соответствующим образом меняются указатели начала и конца.

Операции чтения/записи должны быть выполнены как взаимоисключающие.
Если операция чтения выполняется над пустым буфером (указатель начала = указатель конца), поток-потребитель должен быть заблокирован на условной переменной до тех пор, пока поток-поставщик не запишет в буфер какие-нибудь данные. Если операция записи выполняется над полным буфером, поток-поставщик должен также быть заблокирован на условной переменной до тех пор, пока поток-потребитель не считает из буфера какие-нибудь данные.

Размер буфера – не менее 10 символов.
Поток-поставщик и поток-потребитель работают в бесконечном цикле.
Поток-поставщик производит по одному символу в последовательности 0,1,2...9,0,1,... и записывает его в буфер через случайный интервал времени 0,5 – 2 сек.
Поток-потребитель считывает по одному символу через случайный интервал времени 0,5 – 2 сек из буфера и выводит их на экран в виде сообщений (например, Символ 0, Символ 1,...)
Каждый поток совершая операцию с буфером выводит на экран информацию о текущем состоянии буфера до и после операции, тип операции, символ, состояние условной переменной.

Я вот набросал код программы
Код:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

int buffer[10];
int bdp=1;
int edp=1;

pthread_mutex_t mymtx;
pthread_cond_t mysv;

void* sourser (void *t) {
int t1;
pthread_mutex_lock (&mymtx);
while (1) {
   if ((bdp==1 && edp==10)||(edp==bdp-1))
   pthread_cond_wait (&mysv, &mymtx);
   else {
   buffer[edp]=edp;
   printf ("Simbol %d in\n", buffer[edp]);
   edp=edp+1;
    if (edp>10)
    edp=1;
    pthread_cond_signal (&mysv);
    pthread_mutex_unlock (&mymtx);
    }
    t1=rand()%2000000+500000;
    usleep(t1);
    }
    return;
    }
    
void* extructor (void *d) {
int t2;
pthread_mutex_lock (&mymtx);
while (1) {
  if (edp==bdp)
  pthread_cond_wait (&mysv, &mymtx);
  else {
  buffer[bdp];     
  printf ("Simbol %d out\n", buffer[bdp]);
  buffer[bdp]=0;
  bdp=bdp+1;
    if (bdp>10)
    bdp=1;
    pthread_cond_signal (&mysv);
    pthread_mutex_unlock (&mymtx);
    }
    t2=rand()%2000000+500000;
    usleep(t2);
    }
    return;
    }
    
int main() {
int res;
pthread_t sid, eid;
res=pthread_mutex_init (&mymtx, NULL);
if (res != 0) {
  perror("Mutex initialization failed");
  exit(EXIT_FAILURE);
  }
pthread_cond_init (&mysv, NULL);
res=pthread_create (&sid, NULL, &sourser, NULL);
if (res != 0) {
  perror("Thread creation failed");
  exit(EXIT_FAILURE);
  }
res=pthread_create (&eid, NULL, &extructor, NULL);
if (res != 0) {
  perror("Thread creation failed");
  exit(EXIT_FAILURE);
  }
res=pthread_join (sid, NULL);
if (res != 0) {
  perror("Thread join failed");
  exit(EXIT_FAILURE);
  }
res=pthread_join (eid, NULL);
if (res != 0) {
  perror("Thread join failed");
  exit(EXIT_FAILURE);
  }
return;
}
Но появились такие проблемы как:
1)в данной реализации кольцевого буфера вмещает только 9 символов вместо 10 и при этом ещё происходит выход на границу массива.
2)как задать sleep на 0.5-2с (в данной реализации тут 0.5 до 2.5)?
3)как сюда добавить srand?
4)как убрать много unlock-ов?
Подскажите как решить эти проблемы?
WolfEater вне форума Ответить с цитированием
Старый 01.11.2015, 18:59   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,707
По умолчанию

Цитата:
1)в данной реализации кольцевого буфера вмещает только 9 символов вместо 10 и при этом ещё происходит выход на границу массива.
Массивы нумеруются с 0, а не с 1

Цитата:
2)как задать sleep на 0.5-2с (в данной реализации тут 0.5 до 2.5)?
Поправить
Код:
t2=rand()%2000000+500000;
Цитата:
3)как сюда добавить srand?
Как и в любую другую - перед первым вызовом ренда вызвать. Например, в начале мейна.

Последний раз редактировалось p51x; 01.11.2015 в 19:01.
p51x вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Постоянно слетает галочка "автоматически" в "Параметры Excel", "Формулы", "Вычисления в книге" Alexsandrr Microsoft Office Excel 4 19.10.2013 14:22
Паскаль.Программа "Верификация", "Кака бригадиру разделить заработанные деньги?".Сложные Valik102 Помощь студентам 11 23.06.2009 15:30
Паскаль.Программа "Верификация", "Кака бригадиру разделить заработанные деньги?".Сложные Valik102 Паскаль, Turbo Pascal, PascalABC.NET 3 23.06.2009 09:11
если пользователь наберет какой-то другой символ не "y" или "n" и нажмет enter, программа проигнорирует skobets Общие вопросы C/C++ 2 03.06.2008 06:51