多进程C中的读写器
我有一个C程序,父进程创建一个读线程,然后派生一个子进程,子进程创建多个写线程 写入线程将元素正确地插入共享缓冲区,但读线程什么也不做!当我将所有读写器线程放在一个进程中时,程序工作正常,读写器从缓冲区读取元素!读写器都使用多进程C中的读写器,c,multithreading,semaphore,C,Multithreading,Semaphore,我有一个C程序,父进程创建一个读线程,然后派生一个子进程,子进程创建多个写线程 写入线程将元素正确地插入共享缓冲区,但读线程什么也不做!当我将所有读写器线程放在一个进程中时,程序工作正常,读写器从缓冲区读取元素!读写器都使用sem\u t作为信号量,使用sem\u wait和sem\u post管理对缓冲区的访问 这是我的程序伪代码: int main() { initialize semaphores create reader_thread(reader code) fork child
sem\u t
作为信号量,使用sem\u wait
和sem\u 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
之后不再共享相同的缓冲区。因此,您还需要在父级和子级之间显式共享缓冲区。有很多方法可以做到这一点
在您的例子中,由于您的
结构缓冲区
同时包含信号量和缓冲区,因此您只需将其共享,这将解决1)和2)。您在读/写什么?如果它只是一个普通的C缓冲区,它将无法工作。你需要使用共享内存。至少显示一些实际代码如何?@Drew McGowen,每个写入线程逐块读取图像文件,并将其写入共享缓冲区。共享缓冲区是具有一些字段数组的结构。读卡器线程从缓冲区读取元素并将它们写入一个存储文件。但它实际上是共享内存吗?就像@ScottHunter所说的,您应该发布实际代码;您的伪代码描述得不够。这是您的问题-正常缓冲区没有在fork
之间隐式共享。