I have a homework assignment where I have to implement a circular buffer and add and remove chars with separate threads:
#include <pthread.h>
#include <stdio.h>
#define QSIZE 10
pthread_cond_t full,/* count == QSIZE */
empty,/* count == 0 */
ready;
pthread_mutex_t m, n; /* implements critical section */
unsigned int iBuf, /* tail of circular queue */
oBuf; /* head of circular queue */
int count; /* count characters */
char buf [QSIZE]; /* the circular queue */
void Put(char s[]) {/* add "ch"; wait if full */
pthread_mutex_lock(&m);
int size = sizeof(s)/sizeof(char);
printf("size: %d", size);
int i;
for(i = 0; i < size;开发者_开发问答 i++) {
while (count >= QSIZE)
pthread_cond_wait(&full, &m);/* is there empty slot? */
buf[iBuf] = s[i]; /* store the character */
iBuf = (iBuf+1) % QSIZE; /* increment mod QSIZE */
count++;
if (count == 1)
pthread_cond_signal(&empty);/* new character available */
}
pthread_mutex_unlock(&m);
}
char Get() {/* remove "ch" from queue; wait if empty */
char ch;
pthread_mutex_lock(&m);
while (count <= 0)
pthread_cond_wait(&empty, &m);/* is a character present? */
ch = buf[oBuf]; /* retrieve from the head of the queue */
oBuf = (oBuf+1) % QSIZE;
count--;
if (count == QSIZE-1)
pthread_cond_signal(&full);/* signal existence of a slot */
pthread_mutex_unlock(&m);
return ch;
}
void * p1(void *arg) {
int i;
for (i = 0; i < 5; i++) {
Put("hella");
}
}
void * p2(void *arg) {
int i;
for (i = 0; i < 5; i++) {
Put("goodby");
}
}
int main() {
pthread_t t1, t2;
void *r1, *r2;
oBuf = 0; iBuf = 0; count=0; /* all slots are empty */
pthread_cond_init(&full, NULL);
pthread_cond_init(&empty, NULL);
pthread_mutex_init(&m, NULL);
pthread_create(&t1, NULL, p1, &r1);
pthread_create(&t2, NULL, p2, &r2);
printf("Main");
char c;
int i = 0;
while (i < 55) {
c = Get();
printf("%c",c);
i++;
}
pthread_join(t1, &r1);
pthread_join(t2, &r2);
return 0;
}
I shouldn't have to change the logic much at all, the requirements are pretty specific. I think my problem lies in the Put() method. I think the first thread is going in and blocking the critical section and causing a deadlock. I was thinking I should make a scheduling attribute? Of course I could be wrong. I am pretty new to pthreads and concurrent programming, so I could really use some help spotting my error.
One way to solve this would be to have separate mutexes to manage the head and tail of the circular queue. This way, a writer blocking because the buffer is full will not block a reader.
Another solution would be to release the mutex if you run into the buffer full or empty conditions and reacquire when the condition clears.
-lou
精彩评论