读者 - C 语言的作者 - 我哪里错了?
Readers - writers in C - where am I wrong?
我想寻求有关此任务的帮助。
我的任务是用 C 编写一个简单的程序来模拟 readers-writers 问题。计划要求是:
程序启动后,将要求用户输入作者数和readers。
程序将不断通知用户有关线程的状态。
程序结束后,小统计(每个reader读取和每个写入写入的次数)。
我已经做了一些程序的基本结构(通过信号量等处理临界区),但是我觉得程序没有做的,应该做的。程序运行没有错误或意外行为,但计数,每次 reader 读取和每次写入的次数始终对应每个 reader 或写入器)。
我哪里错了?可能是我没看懂任务
非常感谢您的回复。
程序代码:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t w; // write access
sem_t m; // mutex
int rc=0; // readers count
int writersCount;
int readersCount;
pthread_t writersThread[10], readersThread[10];
int writeCount[10], readCount[10];
int i;
void *writer(void *i) {
int a = *((int *) i);
sem_wait(&w); // P(w)
printf("Writer %d writes to DB.\n",a+1);
writeCount[a+1]++;
sem_post(&w); // V(w)
free(i);
}
void *reader(void *i) {
int a = *((int *) i);
sem_wait(&m); // P(m)
rc++;
if (rc == 1) {
sem_wait(&w); // P(w)
}
sem_post(&m); // V (m)
printf("Reader %d reads from DB.\n",a+1);
readCount[a+1]++;
sem_wait(&m); // P(m)
rc--;
if (rc == 0) {
sem_post(&w); // V(w)
}
sem_post(&m); // V(m)
free(i);
}
int main() {
sem_init(&w,0,1);
sem_init(&m,0,1);
printf("Enter count of writers:");
scanf("%d",&writersCount);
printf("Enter count of readers:");
scanf("%d",&readersCount);
for (i=0; i<readersCount; i++) {
int *arg = malloc(sizeof(*arg));
*arg = i;
pthread_create(&readersThread[i], NULL, reader, arg);
}
for (i=0; i<writersCount; i++) {
int *arg = malloc(sizeof(*arg));
*arg = i;
pthread_create(&writersThread[i], NULL, writer, arg);
}
for (i=0; i<writersCount; i++) {
pthread_join(writersThread[i], NULL);
}
for (i=0; i<readersCount; i++) {
pthread_join(readersThread[i], NULL);
}
printf("--------------\n");
for (i=0; i<readersCount; i++) {
printf("Reader %d read %d times\n",i+1,readCount[i+1]);
}
for (i=0; i<writersCount; i++) {
printf("Writer %d wrote %d times\n",i+1,writeCount[i+1]);
}
sem_destroy(&w);
sem_destroy(&m);
return 0;
}
输出:
输入 writers:4 的计数
输入 readers:4
的计数
Reader 1 reads from DB.
Reader 3 reads from DB.
Reader 4 reads from DB.
Reader 2 reads from DB.
Writer 1 writes to DB.
Writer 2 writes to DB.
Writer 3 writes to DB.
Writer 4 writes to DB.
--------------
Reader 1 read 1 times
Reader 2 read 1 times
Reader 3 read 1 times
Reader 4 read 1 times
Writer 1 wrote 1 times
Writer 2 wrote 1 times
Writer 3 wrote 1 times
Writer 4 wrote 1 times
您的输出完全正确,因为您 运行 的每个线程都只执行一个 read/write。在 reader/writer 函数中放置一些循环来改变这个事实。当您 运行 有 10 个读者或作者时,您的程序可能会遇到错误,因为他们中的一个会尝试访问 writeCount[10]
或 readCount[10]
,更改它并且您有一个正确的程序。
你可以试试这个,但是请选择 vasicbre 的答案,因为他是第一个发现问题的人。
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t w; // write access
sem_t m; // mutex
int rc=0; // readers count
int writersCount;
int readersCount;
pthread_t writersThread[100], readersThread[100];
int writeCount[10], readCount[10];
void *writer(void *i)
{
int a = *((int *) i);
sem_wait(&w); // P(w)
printf("Writer %d writes to DB.\n",a+1);
writeCount[a + 1]++;
sem_post(&w); // V(w)
return NULL;
}
void *reader(void *i)
{
int a = *((int *) i);
sem_wait(&m); // P(m)
rc++;
if (rc == 1) {
sem_wait(&w); // P(w)
}
sem_post(&m); // V (m)
printf("Reader %d reads from DB.\n", a + 1);
readCount[a + 1]++;
sem_wait(&m); // P(m)
rc--;
if (rc == 0) {
sem_post(&w); // V(w)
}
sem_post(&m); // V(m)
return NULL;
}
int randomCount()
{
return 5.0 * rand() / RAND_MAX;
}
int main()
{
sem_init(&w,0,1);
sem_init(&m,0,1);
int i;
printf("Enter count of writers:");
scanf("%d",&writersCount);
printf("Enter count of readers:");
scanf("%d",&readersCount);
int readerIndices[readersCount];
int writerIndices[writersCount];
int totalReaders = 0;
int totalWriters = 0;
for (i=0; i<readersCount; i++)
{
int j;
int count;
readerIndices[i] = i;
count = randomCount();
for (j = 0 ; j < count ; ++j)
{
pthread_create(&readersThread[totalReaders++], NULL, reader, &readerIndices[i]);
}
}
for (i = 0 ; i < writersCount ; i++)
{
int j;
int count;
writerIndices[i] = i;
count = randomCount();
for (j = 0 ; j < count ; ++j)
{
pthread_create(&writersThread[totalWriters++], NULL, writer, &writerIndices[i]);
}
}
for (i = 0 ; i < totalWriters ; i++)
{
pthread_join(writersThread[i], NULL);
}
for (i = 0 ; i < totalReaders ; i++)
{
pthread_join(readersThread[i], NULL);
}
printf("--------------\n");
for (i = 0 ; i < readersCount ; i++)
{
printf("Reader %d read %d times\n", i + 1, readCount[i + 1]);
}
for (i = 0 ; i < writersCount ; i++)
{
printf("Writer %d wrote %d times\n", i + 1, readCount[i + 1]);
}
sem_destroy(&w);
sem_destroy(&m);
return 0;
}
我想寻求有关此任务的帮助。
我的任务是用 C 编写一个简单的程序来模拟 readers-writers 问题。计划要求是:
程序启动后,将要求用户输入作者数和readers。
程序将不断通知用户有关线程的状态。
程序结束后,小统计(每个reader读取和每个写入写入的次数)。
我已经做了一些程序的基本结构(通过信号量等处理临界区),但是我觉得程序没有做的,应该做的。程序运行没有错误或意外行为,但计数,每次 reader 读取和每次写入的次数始终对应每个 reader 或写入器)。
我哪里错了?可能是我没看懂任务
非常感谢您的回复。
程序代码:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t w; // write access
sem_t m; // mutex
int rc=0; // readers count
int writersCount;
int readersCount;
pthread_t writersThread[10], readersThread[10];
int writeCount[10], readCount[10];
int i;
void *writer(void *i) {
int a = *((int *) i);
sem_wait(&w); // P(w)
printf("Writer %d writes to DB.\n",a+1);
writeCount[a+1]++;
sem_post(&w); // V(w)
free(i);
}
void *reader(void *i) {
int a = *((int *) i);
sem_wait(&m); // P(m)
rc++;
if (rc == 1) {
sem_wait(&w); // P(w)
}
sem_post(&m); // V (m)
printf("Reader %d reads from DB.\n",a+1);
readCount[a+1]++;
sem_wait(&m); // P(m)
rc--;
if (rc == 0) {
sem_post(&w); // V(w)
}
sem_post(&m); // V(m)
free(i);
}
int main() {
sem_init(&w,0,1);
sem_init(&m,0,1);
printf("Enter count of writers:");
scanf("%d",&writersCount);
printf("Enter count of readers:");
scanf("%d",&readersCount);
for (i=0; i<readersCount; i++) {
int *arg = malloc(sizeof(*arg));
*arg = i;
pthread_create(&readersThread[i], NULL, reader, arg);
}
for (i=0; i<writersCount; i++) {
int *arg = malloc(sizeof(*arg));
*arg = i;
pthread_create(&writersThread[i], NULL, writer, arg);
}
for (i=0; i<writersCount; i++) {
pthread_join(writersThread[i], NULL);
}
for (i=0; i<readersCount; i++) {
pthread_join(readersThread[i], NULL);
}
printf("--------------\n");
for (i=0; i<readersCount; i++) {
printf("Reader %d read %d times\n",i+1,readCount[i+1]);
}
for (i=0; i<writersCount; i++) {
printf("Writer %d wrote %d times\n",i+1,writeCount[i+1]);
}
sem_destroy(&w);
sem_destroy(&m);
return 0;
}
输出: 输入 writers:4 的计数 输入 readers:4
的计数Reader 1 reads from DB.
Reader 3 reads from DB.
Reader 4 reads from DB.
Reader 2 reads from DB.
Writer 1 writes to DB.
Writer 2 writes to DB.
Writer 3 writes to DB.
Writer 4 writes to DB.
--------------
Reader 1 read 1 times
Reader 2 read 1 times
Reader 3 read 1 times
Reader 4 read 1 times
Writer 1 wrote 1 times
Writer 2 wrote 1 times
Writer 3 wrote 1 times
Writer 4 wrote 1 times
您的输出完全正确,因为您 运行 的每个线程都只执行一个 read/write。在 reader/writer 函数中放置一些循环来改变这个事实。当您 运行 有 10 个读者或作者时,您的程序可能会遇到错误,因为他们中的一个会尝试访问 writeCount[10]
或 readCount[10]
,更改它并且您有一个正确的程序。
你可以试试这个,但是请选择 vasicbre 的答案,因为他是第一个发现问题的人。
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t w; // write access
sem_t m; // mutex
int rc=0; // readers count
int writersCount;
int readersCount;
pthread_t writersThread[100], readersThread[100];
int writeCount[10], readCount[10];
void *writer(void *i)
{
int a = *((int *) i);
sem_wait(&w); // P(w)
printf("Writer %d writes to DB.\n",a+1);
writeCount[a + 1]++;
sem_post(&w); // V(w)
return NULL;
}
void *reader(void *i)
{
int a = *((int *) i);
sem_wait(&m); // P(m)
rc++;
if (rc == 1) {
sem_wait(&w); // P(w)
}
sem_post(&m); // V (m)
printf("Reader %d reads from DB.\n", a + 1);
readCount[a + 1]++;
sem_wait(&m); // P(m)
rc--;
if (rc == 0) {
sem_post(&w); // V(w)
}
sem_post(&m); // V(m)
return NULL;
}
int randomCount()
{
return 5.0 * rand() / RAND_MAX;
}
int main()
{
sem_init(&w,0,1);
sem_init(&m,0,1);
int i;
printf("Enter count of writers:");
scanf("%d",&writersCount);
printf("Enter count of readers:");
scanf("%d",&readersCount);
int readerIndices[readersCount];
int writerIndices[writersCount];
int totalReaders = 0;
int totalWriters = 0;
for (i=0; i<readersCount; i++)
{
int j;
int count;
readerIndices[i] = i;
count = randomCount();
for (j = 0 ; j < count ; ++j)
{
pthread_create(&readersThread[totalReaders++], NULL, reader, &readerIndices[i]);
}
}
for (i = 0 ; i < writersCount ; i++)
{
int j;
int count;
writerIndices[i] = i;
count = randomCount();
for (j = 0 ; j < count ; ++j)
{
pthread_create(&writersThread[totalWriters++], NULL, writer, &writerIndices[i]);
}
}
for (i = 0 ; i < totalWriters ; i++)
{
pthread_join(writersThread[i], NULL);
}
for (i = 0 ; i < totalReaders ; i++)
{
pthread_join(readersThread[i], NULL);
}
printf("--------------\n");
for (i = 0 ; i < readersCount ; i++)
{
printf("Reader %d read %d times\n", i + 1, readCount[i + 1]);
}
for (i = 0 ; i < writersCount ; i++)
{
printf("Writer %d wrote %d times\n", i + 1, readCount[i + 1]);
}
sem_destroy(&w);
sem_destroy(&m);
return 0;
}