У меня есть несколько процессов, которые могут получить доступ к блоку общей памяти.Только один процесс будет время от времени записывать в общую память, несколько других процессов могут время от времени читать из общей памяти.Я не хочу реализовывать следующий сценарий:
- читатель должен ждать, пока писатель не пишет, прежде чем он прочитает из общей памяти;
- писатель должен ждать, пока не будет читателячитает перед записью в общую память;
- считыватели могут читать из общей памяти одновременно.
Я пытался использовать процесс общего мьютекса и флаги в общей памяти для реализации этого сценария.(разделяемый мьютекс процесса используется для защиты флага):
- , когда писатель хочет выполнить запись в общую память: дождитесь, пока флаг читателя не станет равным 0 -> установите флаг писателя в 1 ->запись в разделяемую память -> установить флаг записи на 0
- , когда считыватель хочет прочитать из общей памяти: подождите, пока флаг записи не станет 0 -> увеличить флаг читателя -> читать из общей памяти -> уменьшить флаг читателя
Код выглядит следующим образом:
typedef struct {
pthread_mutex_t rw_mutex;
int read_flag;
int write_flag;
} shared_data_t;
void read_start(shared_data_t *p_data)
{
while (1)
{
pthread_mutex_lock(&p_data->rw_mutex);
if (p_data->write_flag <= 0)
{
p_data->read_flag++;
pthread_mutex_unlock(&p_data->rw_mutex);
break;
}
else
{
pthread_mutex_unlock(&p_data->rw_mutex);
usleep(1);
}
}
}
void read_finish(shared_data_t *p_data)
{
pthread_mutex_lock(&p_data->rw_mutex);
p_data->read_flag--;
pthread_mutex_unlock(&p_data->rw_mutex);
}
void write_start(shared_data_t *p_data)
{
while (1)
{
pthread_mutex_lock(&p_data->rw_mutex);
if (p_data->read_flag <= 0)
{
printf("set write flag to 1\n");
p_data->write_flag = 1;
pthread_mutex_unlock(&p_data->rw_mutex);
break;
}
else
{
pthread_mutex_unlock(&p_data->rw_mutex);
usleep(1);
}
}
}
void write_finish(shared_data_t *p_data)
{
pthread_mutex_lock(&p_data->rw_mutex);
p_data->write_flag = 0;
pthread_mutex_unlock(&p_data->rw_mutex);
}
Процесс записи писателя выглядит так:
write_start(p_data);
//write data
write_finish(p_data);
Процесс чтения читателя выглядит следующим образом:
read_start(p_data);
//read data
read_finish(p_data);
Код работает, но я не проверял, есть ли потенциальные ошибки.
Я думаю, что должен быть какой-то лучший способ реализовать этот сценарий.Любое предложение приветствуется!
EDIT1: Я попытался использовать сигнал условия, чтобы заменить использование usleep, и код выглядит помет лучше.
typedef struct {
pthread_mutex_t rw_mutex;
pthread_cond_t rw_cond;
int read_flag;
int write_flag;
} shared_data_t;
void read_start(shared_data_t *p_data)
{
while (1)
{
pthread_mutex_lock(&p_data->rw_mutex);
if (p_data->write_flag <= 0)
{
p_data->read_flag++;
pthread_mutex_unlock(&p_data->rw_mutex);
break;
}
else
{
pthread_cond_wait(&p_data->rw_cond, &p_data->rw_mutex);
pthread_mutex_unlock(&p_data->rw_mutex);
}
}
}
void read_finish(shared_data_t *p_data)
{
pthread_mutex_lock(&p_data->rw_mutex);
p_data->read_flag--;
pthread_cond_broadcast(&p_data->rw_cond);
pthread_mutex_unlock(&p_data->rw_mutex);
}
void write_start(shared_data_t *p_data)
{
while (1)
{
pthread_mutex_lock(&p_data->rw_mutex);
if (p_data->read_flag <= 0 && p_data->write_flag <= 0)
{
printf("set write flag to 1\n");
p_data->write_flag = 1;
pthread_mutex_unlock(&p_data->rw_mutex);
break;
}
else
{
pthread_cond_wait(&p_data->rw_cond, &p_data->rw_mutex);
pthread_mutex_unlock(&p_data->rw_mutex);
}
}
}
void write_finish(shared_data_t *p_data)
{
pthread_mutex_lock(&p_data->rw_mutex);
p_data->write_flag = 0;
pthread_cond_broadcast(&p_data->rw_cond);
pthread_mutex_unlock(&p_data->rw_mutex);
}