Использование всей семафорной программы вместо mutex и cond_t - PullRequest
0 голосов
/ 25 ноября 2018

Я новичок в C, и я просто больше учился в книге, которую взял.Я получил блокировки мьютекса и условные переменные и все в таком духе.В книге я видел упражнение, в котором говорилось, что нужно переключить программу с мьютекс-блокировками и условно на программу, в которой вместо этого используются семафоры для достижения тех же результатов.В данный момент я застрял, потому что когда я запускаю код, я полагаю, что у меня возникает ситуация «тупиковой ситуации», и после этого ничего не происходит.Я не уверен, что не так, но любая помощь будет оценена.Это то, что у меня сейчас.

int main(){
  pthread_t pid;
  pthread_t cid;

  sem_init(&empty, 1, BUFSIZE);
  sem_init(&full, 1, BUFSIZE);

  randData =  (unsigned int) time(NULL);

  printf("Creating threads\n\n");

  pthread_create(&pid, NULL, produce, ids);
  pthread_create(&cid, NULL, consume, ids);  
  pthread_join(pid, NULL);
  pthread_join(cid, NULL);
}

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

Похоже, ваше решение довольно близко, но у вас все еще есть кое-что из условия / остатка, которое вам не нужно.Например, когда поток принимает соответствующий семафор, он знает, что он может продолжаться.

Проверьте меня по этому коду - могут быть некоторые проблемы, но вот что я бы порекомендовал (это псевдо C)

void* produce(void* arg)
{ 
  // Wait for any item to be present in queue
  sem_wait(&isNotFullSem);

  // Take "mutex" to protect buffer
  sem_wait(&mutex);

  // Enqueue new value
  enter(value);

  // Release mutex
  sem_post(&mutex);

  // Signal that buffer is not empty
  //  (probably not the best name, but similar to condition)
  sem_post(&isNotEmptySem);
}

void* consume(void* arg)
{
  // Wait for empty space to be present in queue
  sem_wait(&isNotEmptySem);

  // Take "mutex" to protect buffer
  sem_wait(&mutex);

  // Enqueue new value
  value = leave();

  // Release mutex
  sem_post(&mutex);

  // Signal that buffer is not full
  sem_post(&isNotFullSem);
}
0 голосов
/ 25 ноября 2018

В коде для производителя ниже функция mutex_wait () предназначена для одного и того же "mutex" дважды, который может блокироваться, в то время как post () используется только один раз для потребителя.

sem_wait(&empty);
sem_wait(&mutex);  <---
while ( isFull() ){
  printf("%*sProducer %d waits\n", id*5, "", id);
}

enter(value);
printf("%*sProducer %d stores %d    ", id*5, "", id, value);
print();
printf("\n");

sem_wait(&mutex);  <---
sem_post(&full);

Несколько идей, чтобы привести его в хорошую формуis Когда есть ожидание пустого или полного, просто добавьте одну проверку, а не зацикливание, и сделайте mutex wait () в производителе и из потребителя post (), когда оно пустое или не заполнено.

...