簡體   English   中英

多個進程中的讀寫器C

[英]Reader-Writer in multiple processes C

我有一個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
}

這里至少有兩個問題:1)父進程和子進程之間是否共享sem_t full/empty/mutex 2)緩沖區是否在父進程和子進程之間共享。

1)由於子進程駐留在單獨的地址空間中,因此它不再與父進程共享相同的sem_t 因此,您需要顯式地共享這些信號。 結果,讀取器和寫入器無法正確同步。 您可以參考這篇文章 ,了解如何共享信號量。

2)類似地,由於寫時復制機制,在fork之后,父進程中的讀取器線程和子進程中的寫入器線程不再共享同一緩沖區。 因此,您還需要在父級和子級之間顯式共享緩沖區。 幾種方法可以做到這一點。

在您的情況下,由於您的struct Buffer包含信號量和緩沖區,因此您只需要使其共享即可,這將同時解析1)和2)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM