我已经声明了一个类似于下面的结构,当我编译时,我有很多错误,如:
error: 'struct RW' has no member named 'num_writes'
error: 'struct RW' has no member named 'writer_cv'
error: 'struct RW' has no member named 'reader_cv'
error: 'struct RW' has no member named 'lock'
我认为使用前向声明可以解决问题,但似乎不是。或者我这样做错了?
#include <stdio.h>
#include <pthread.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
struct RW;
struct RW{
volatile int num_reads_in_progress;
volatile int num_writes;
pthread_cond_t reader_cv;
pthread_cond_t writer_cv;
pthread_mutex_t lock;
};
char *buf;
//Precondition: b->lock must be locked before this function is called
void signal_next(struct RW *b){
if(b->num_writes > 0){
//if any writes are waiting wake one up
pthread_cond_signal(&b->writer_cv);
}
else{
//if are no writes pending, wake up all the readers
pthread_cond_broadcast(&b->reader_cv);
}
}
char *ts_read(struct RW *b){
pthread_mutex_lock(&b->lock);
while(b->num_writes > 0){
//cond_wait unlocks the mutex, waits to be signaled, then re-acquires the mutex
pthread_cond_wait(&b->reader_cv,&b->lock);
}
//By there b->num_writes must be 0
b->num_reads_in_progress++;
pthread_mutex_unlock(&b->lock);
buf = read(b);
pthread_mutex_lock(&b->lock);
b->num_reads_in_progress--;
signal_next(b);
pthread_mutex_unlock(&b->lock);
}
void ts_write(struct RW *b) {
pthread_mutex_lock(&b->lock);
b->num_writes++;
if (b->num_writes > 1 || b->num_reads_in_progress > 0)
{
// cond_wait unlocks the mutex, waits to be signaled,
// then re-acquires the mutex
pthread_cond_wait(&b->writer_cv, &b->lock);
}
pthread_mutex_unlock(&b->lock);
write(b, buf);
pthread_mutex_lock(&b->lock);
b->num_writes--;
signal_next(b);
pthread_mutex_unlock(&b->lock);
}
int main(){
pthread_t white[3];
pthread_t black[3];
struct RW *rw ;
rw = malloc(sizeof RW);
int i;
for(i = 0; i < 3; i++){
pthread_create(&white[i],NULL,&ts_read,&rw);
}
for(i = 0; i < 3; i++){
pthread_create(&black[i],NULL,ts_write,&rw);
}
for(i = 0; i < 3; i++){
pthread_join(white[i],NULL);
}
for(i = 0; i < 3; i++){
pthread_join(black[i],NULL);
}
return 0;
}
错误:
error: expected ':', ',', ';','}' or '_attribute_'before 'num_writes'
In function 'signal_next':
error: 'struct RW' has no member named 'num_writes'
error: 'struct RW' has no member named 'writer_cv'
error: 'struct RW' has no member named 'reader_cv'
In function 'ts_read':
error: 'struct RW' has no member named 'num_writes'
error: 'struct RW' has no member named 'writer_cv'
error: 'struct RW' has no member named 'reader_cv'
error: 'struct RW' has no member named 'lock'
与ts_read
和ts_write
main
相同的错误
答案 0 :(得分:0)
此代码使用命令行在Mac OS X 10.9 Mavericks上使用GCC 4.8.2编译时没有警告:
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c ptc.c
由于使用了编译器选项,函数定义之前的函数声明是必需的;我通常通过使函数静态而不是重复自己来解决问题,但这取决于是否在其他文件中需要这些函数。如果在其他地方需要它们,那么声明当然会在标题中出现。
我已使用/* Fix */
标记了问题代码中的大部分更改。
#include <stdio.h>
#include <pthread.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
struct RW;
struct RW
{
volatile int num_reads_in_progress;
volatile int num_writes;
pthread_cond_t reader_cv;
pthread_cond_t writer_cv;
pthread_mutex_t lock;
};
char *buf;
void signal_next(struct RW *b);
// Precondition: b->lock must be locked before this function is called
void signal_next(struct RW *b)
{
if (b->num_writes > 0)
{
// if any writes are waiting wake one up
pthread_cond_signal(&b->writer_cv);
}
else
{
// if are no writes pending, wake up all the readers
pthread_cond_broadcast(&b->reader_cv);
}
}
extern char *xx_read(struct RW *); /* Fix */
void *ts_read(void *vb);
void *ts_read(void *vb) /* Fix */
{
struct RW *b = vb; /* Fix */
pthread_mutex_lock(&b->lock);
while (b->num_writes > 0)
{
// cond_wait unlocks the mutex, waits to be signaled, then re-acquires the mutex
pthread_cond_wait(&b->reader_cv, &b->lock);
}
// By there b->num_writes must be 0
b->num_reads_in_progress++;
pthread_mutex_unlock(&b->lock);
buf = xx_read(b); /* Fix */
pthread_mutex_lock(&b->lock);
b->num_reads_in_progress--;
signal_next(b);
pthread_mutex_unlock(&b->lock);
return 0; /* Fix */
}
extern void xx_write(struct RW *, char *); /* Fix */
void *ts_write(void *vb);
void *ts_write(void *vb) /* Fix */
{
struct RW *b = vb; /* Fix */
pthread_mutex_lock(&b->lock);
b->num_writes++;
if (b->num_writes > 1 || b->num_reads_in_progress > 0)
{
// cond_wait unlocks the mutex, waits to be signaled,
// then re-acquires the mutex
pthread_cond_wait(&b->writer_cv, &b->lock);
}
pthread_mutex_unlock(&b->lock);
xx_write(b, buf); /* Fix */
pthread_mutex_lock(&b->lock);
b->num_writes--;
signal_next(b);
pthread_mutex_unlock(&b->lock);
return 0; /* Fix */
}
int main(void)
{
pthread_t white[3];
pthread_t black[3];
struct RW *rw;
rw = malloc(sizeof(struct RW)); /* Fix */
int i;
for (i = 0; i < 3; i++)
{
pthread_create(&white[i], NULL, &ts_read, &rw);
}
for (i = 0; i < 3; i++)
{
pthread_create(&black[i], NULL, ts_write, &rw);
}
for (i = 0; i < 3; i++)
{
pthread_join(white[i], NULL);
}
for (i = 0; i < 3; i++)
{
pthread_join(black[i], NULL);
}
return 0;
}
我制作了这个社区Wiki,因为在我之前有很多其他人的努力。我没有阅读所有评论,但它们似乎与我所做的改变基本相同。