免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1241 | 回复: 0
打印 上一主题 下一主题

[Linux] 关于linux 信号量的问题。欢迎大家来知道下(附程序) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-11-06 15:01 |只看该作者 |倒序浏览
这是生产者消费者问题。
我打个比方,有多个生产者,他们都生产牛奶放入超市,而有多个消费者进入超市消费买牛奶。生产者与消费者之间可以同步操作,但是生产者与生产者之间、消费者与消费者之间要进行互斥操作。

以下是我在某本书看到的例子(原例是一个生产者一个消费者),然后自己进行了修改(多个生产者一个消费者),程序收尾部分我暂时未编写。
请大家帮我看看这个程序,不知道出了那些问题。还有请大家给解释下信号量。最好能

信号量可以同时两个线程sem_wait 、sem_post实现-2、+2操作  我主要是想实现这种情况。
如果是二值信号量那就跟互斥锁差不多了。
以下是程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <semaphore.h>

#define BUFFER_SIZE 6

struct prodcons {
int buffer[BUFFER_SIZE];
//pthread_mutex_t getlock; //程序中只有一个消费者线程,所以可以暂时不用这个消费者间互斥锁
pthread_mutex_t putlock;//生产者间互斥锁
int readpos, writepos;//读写位置
sem_t sem;
pthread_cond_t notempty;//提示非空
pthread_cond_t notfull;//提示非满
};

void init(struct prodcons * b)
{
pthread_mutex_init(&b->putlock,NULL);
//pthread_mutex_init(&b->getlock,NULL);
pthread_cond_init(&b->notempty,NULL);
pthread_cond_init(&b->notfull,NULL);
sem_init(&b->sem,0,0);
b->readpos = 0;
b->writepos = 0;
}

void put(struct prodcons * b, int data)
{
pthread_mutex_lock(&b->putlock);
while((b->writepos + 1) % BUFFER_SIZE == b->readpos) {
printf("wait for not full\n");
pthread_cond_wait(&b->notfull,&b->putlock);
}
sem_post(&b->sem);
b->buffer[b->writepos] = data;
b->writepos++;
if (b->writepos >= BUFFER_SIZE) b->writepos = 0;
pthread_cond_signal(&b->notempty);
pthread_mutex_unlock(&b->putlock);
}

int get (struct prodcons * b)
{
int data;
pthread_mutex_lock(&b->getlock);
while (b->writepos == b->readpos){
     printf("wait for not empty\n");
     pthread_cond_wait(&b->notempty,&b->getlock);
}
sem_wait(&b->sem);
data = b->buffer[b->readpos];
b->readpos++;
if(b->readpos >= BUFFER_SIZE) b->readpos = 0;
pthread_cond_signal(&b->notfull);
pthread_mutex_unlock(&b->getlock);
return data;
}

#define OVER (-1)
struct prodcons buffer;

void *producer(void * data)
{
int n,pthid;
pthid=pthread_self();
for(n = 0; n < 10; n++){
printf("producer PID=%d put-->%d\n",pthid,n);
put(&buffer,n);
sleep(1);}
//put(&buffer,OVER);
printf("producer PID=%d stopped\n",pthid);
return NULL;
}

void *consumer(void * data)
{
int d,pthid;
pthid=pthread_self();
while (1){
d = get(&buffer);
//if (d == OVER) break;
printf("consumer PID=%d %d-->get\n",pthid,d);
sleep(1);
}
printf("consumer PID=%d stopped\n",pthid);
return NULL;
}

int main(void)
{
pthread_t th_a,th_b,th_c;
void * retval;
init(&buffer);

pthread_create(&th_c,NULL,producer,0);
pthread_create(&th_a,NULL,producer,0);
pthread_create(&th_b,NULL,consumer,0);
pthread_join(th_a,&retval);
pthread_join(th_b,&retval);
pthread_join(th_c,&retval);
return 0;
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP