C - 带 pthreads 的循环字符缓冲区
我有一个家庭作业,我必须实现一个循环缓冲区,并使用单独的线程添加和删除字符:
#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;
}
我根本不需要改变太多逻辑,要求非常具体。我认为我的问题出在 Put() 方法上。我认为第一个线程正在进入并阻塞关键部分并导致死锁。我在想我应该做一个调度属性吗?当然我可能是错的。我对 pthreads 和并发编程非常陌生,所以我真的需要一些帮助来发现我的错误。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决这个问题的一种方法是使用单独的互斥体来管理循环队列的头部和尾部。这样,由于缓冲区已满而阻塞的写入器不会阻塞读取器。
另一种解决方案是,如果遇到缓冲区满或空的情况,则释放互斥体,并在条件清除时重新获取。
-楼
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