C 结构问题的定义

C 结构问题的定义,c,linux,C,Linux,我声明了一个如下所示的结构,当我编译时,我有很多错误,如: 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' 我原以为使用转发声明可以解决问题,但事

我声明了一个如下所示的结构,当我编译时,我有很多错误,如:

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;


}

对于
ts_write
main

,与
ts_read
中的错误相同。此代码使用命令行在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;
}
#包括
#包括
#包括
#包括
#包括
结构RW;
结构RW
{
volatile int num读取进行中的数据;
volatile int num_写入;
pthread_cond_t reader_cv;
pthread_cond_t writer_cv;
pthread_mutex_t lock;
};
char*buf;
无效信号_next(结构RW*b);
//前提条件:调用此函数之前,必须先锁定b->lock
下一个无效信号(结构RW*b)
{
如果(b->num\u写入>0)
{
//如果有写操作正在等待,请唤醒一个
pthread_cond_信号(&b->writer_cv);
}
其他的
{
//如果没有等待写入,请唤醒所有读卡器
pthread_cond_broadcast(&b->reader_cv);
}
}
外部字符*xx_读取(结构RW*);/*修理*/
void*ts_read(void*vb);
void*ts_读取(void*vb)/*修复*/
{
结构RW*b=vb;/*Fix*/
pthread_mutex_lock(&b->lock);
而(b->num_写入>0)
{
//cond_wait解锁互斥锁,等待发出信号,然后重新获取互斥锁
pthread\u cond\u wait(&b->reader\u cv,&b->lock);
}
//此时,b->num\u写入必须为0
b->num_读取_进度++;
pthread_mutex_unlock(&b->lock);
buf=xx_读取(b);/*修复*/
pthread_mutex_lock(&b->lock);
b->num_读取正在进行的数据--;
信号_next(b);
pthread_mutex_unlock(&b->lock);
返回0;/*修复*/
}
外部无效xx_写入(结构RW*,字符*);/*修理*/
void*ts_写入(void*vb);
void*ts_write(void*vb)/*修复*/
{
结构RW*b=vb;/*Fix*/
pthread_mutex_lock(&b->lock);
b->num_写入++;
如果(b->num|u writes>1;b->num|u reads_in_progress>0)
{
//cond_wait解锁互斥锁,等待发出信号,
//然后重新获取互斥锁
pthread\u cond\u wait(&b->writer\u cv,&b->lock);
}
pthread_mutex_unlock(&b->lock);
xx_写入(b,buf);/*修复*/
pthread_mutex_lock(&b->lock);
b->num_写入--;
信号_next(b);
pthread_mutex_unlock(&b->lock);
返回0;/*修复*/
}
内部主(空)
{
pthread_t white[3];
pthread_t black[3];
结构RW*RW;
rw=malloc(sizeof(struct rw));/*Fix*/
int i;
对于(i=0;i<3;i++)
{
pthread_create(&white[i],NULL,&ts_read,&rw);
}
对于(i=0;i<3;i++)
{
pthread_create(&black[i],NULL,ts_write,&rw);
}
对于(i=0;i<3;i++)
{
pthread_join(白色[i],NULL);
}
对于(i=0;i<3;i++)
{
pthread_join(黑色[i],NULL);
}
返回0;
}

我之所以创建这个社区Wiki,是因为在我之前,其他人做了很多工作。我没有阅读所有的评论,但它们似乎涵盖了与我所做的更改大致相同的内容。

转发声明不会改变此代码段中的任何内容。立即转发不会改变任何内容。确保您使用的是正确的RW结构。如果您向我们展示了使用该结构的位置,这也会有所帮助。也可以决定是否是C++或C,这是重要的。显示模式代码,特别是代码中出现错误的部分。你必须告诉我们你如何使用这个结构,尤其是代码(带有一些周围的上下文,比如变量声明),在这些地方你会得到这些错误。@劳拉:第一个错误(所有其他的都是第一个的效果)要么是一些看不见的垃圾,要么是虚假的预处理器定义。因为我们现在有在线编译器,你能不能将示例粘贴到一些(例如,但是还有很多其他的),这样我们就可以看到编译器的直接输出?
#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;
}