【问题标题】:Reader-Writer in multiple processes C多进程C中的读写器
【发布时间】:2014-08-14 14:21:57
【问题描述】:

我有一个 C 程序,父进程创建一个读取器线程,然后派生一个子进程,子进程创建多个写入器线程。

写入线程正确地将元素插入共享缓冲区,但读取线程不做任何事情!当我将所有读取器和写入器线程放在一个进程中时,程序正常工作并且读取器从缓冲区中读取元素!读取器和写入器都使用sem_t 作为信号量,使用sem_waitsem_post 管理对缓冲区的访问。

这是我的程序伪代码:

int main()
{
initialize semaphores

create reader_thread(reader code)

fork child process(server)
}

int server()
{
create writer threads(writer code)
}

这是缓冲区结构:

typedef struct
{
    Req_info reqinfo[BUFFER_SIZE];
    char chunk[BUFFER_SIZE][MAX_CHUNK_SIZE];
    uint64_t chunk_size[BUFFER_SIZE];
    int Isnewfile[BUFFER_SIZE];     //1 means new file
    int Islastchunk[BUFFER_SIZE];   //1 means last chunk
    int ID[BUFFER_SIZE];
    int head;
    int tail;
    int numofelement;
#ifdef SEM_V
    sem_t full;
    sem_t empty;
    sem_t mutex;
#else
    pthread_mutex_t mutex;
    pthread_cond_t cond_read;
    pthread_cond_t cond_write;
#endif
} Buffer;

Buffer *buffer_ptr;


void writer()
{
#ifdef SEM_V
    sem_wait(&buffer_ptr->empty);
    sem_wait(&buffer_ptr->mutex);
#else
    pthread_mutex_lock(&buffer_ptr->mutex);

    if((buffer_ptr->tail + 1) % BUFFER_SIZE == buffer_ptr->head)
    pthread_cond_wait( &buffer_ptr->cond_write, &buffer_ptr->mutex );

    pthread_mutex_unlock(&buffer_ptr->mutex);

    pthread_mutex_lock(&buffer_ptr->mutex);
#endif

    if ((buffer_ptr->tail + 1) % BUFFER_SIZE != buffer_ptr->head)
    {

    memmove(buffer_ptr->chunk[buffer_ptr->tail], chunk, chunk_size);    //Write chunk into buffer
    buffer_ptr->chunk[buffer_ptr->tail][chunk_size] = '\0';

    buffer_ptr->chunk_size[buffer_ptr->tail] = chunk_size;          //Write chunk size into buffer

    buffer_ptr->Isnewfile[buffer_ptr->tail] = Isnewfile;

    buffer_ptr->Islastchunk[buffer_ptr->tail] = Islastchunk;

    buffer_ptr->reqinfo[buffer_ptr->tail] = reqinfo;

    buffer_ptr->ID[buffer_ptr->tail] = ID;

    buffer_ptr->tail = (buffer_ptr->tail + 1) % BUFFER_SIZE;

    }
#ifdef SEM_V
    sem_post(&buffer_ptr->mutex);
    sem_post(&buffer_ptr->full);
#else

    pthread_cond_signal(&buffer_ptr->cond_write);
    pthread_mutex_unlock(&buffer_ptr->mutex);
#endif
}


void reader()
{
#ifdef SEM_V
        sem_wait(&buffer_ptr->full);
#endif

        if (buffer_ptr->tail != buffer_ptr->head)
            {

        if(!first){
            gettimeofday(&ts, NULL);
            first = 1;
        }

        chunksize = buffer_ptr->chunk_size[buffer_ptr->head];           //Read chunk size from buffer

        memmove(chunk, buffer_ptr->chunk[buffer_ptr->head], chunksize);     //Read chunk from buffer
        chunk[chunksize] = '\0';

        Isnewfile = buffer_ptr->Isnewfile[buffer_ptr->head];
        Islastchunk = buffer_ptr->Islastchunk[buffer_ptr->head];

        reqinfo = buffer_ptr->reqinfo[buffer_ptr->head];

        ID = buffer_ptr->ID[buffer_ptr->head];

            buffer_ptr->head = (buffer_ptr->head + 1) % BUFFER_SIZE;

            }
        else{
#ifdef SEM_V
        sem_post(&buffer_ptr->empty);
#endif
        continue;
        }
#ifdef SEM_V
        sem_post(&buffer_ptr->empty);
#endif
}

【问题讨论】:

  • 你在读/写什么?如果它只是一个普通的 C 缓冲区,它将无法工作。您需要使用共享内存。
  • 至少显示一些实际代码怎么样?
  • @Drew McGowen,每个写入线程逐块读取图像文件并将其写入共享缓冲区。共享缓冲区是一个包含一些字段数组的结构。读取线程从缓冲区中读取元素并将它们写入一个存储文件。
  • 它实际上是共享内存吗?就像@ScottHunter 所说,你应该发布 actual 代码;你的伪代码描述不够。
  • 这是你的问题 - 普通缓冲区不会在 fork 之间隐式共享。

标签: c multithreading semaphore


【解决方案1】:

这里至少有两个问题:1)sem_t full/empty/mutex是否在父进程和子进程之间共享; 2) 父进程和子进程之间是否共享缓冲区。

1) 由于子进程驻留在单独的地址空间中,它不再与父进程共享相同的sem_t。因此,您需要明确地使这些信号量共享。结果,读取器和写入器无法正确同步。信号量分享方法可以参考this post

2) 同样由于copy-on-write机制,在fork之后,父进程中的读取线程和子进程中的写入线程不再共享同一个缓冲区。因此,您还需要在父子节点之间显式共享缓冲区。有several ways 可以做到这一点。

在您的情况下,由于您的 struct Buffer 包含信号量和缓冲区,您只需将其设为共享,这将解决 1) 和 2)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    相关资源
    最近更新 更多