#include"sys/types.h"
#include"sys/file.h"
#include"unistd.h"
char r_buf[4];//读缓冲
char w_buf[4];//写缓冲
int pipe_fd[2];//两个通道
pid_t pid1,pid2,pid3,pid4;//四个进程
int producer(int id);//生产者
int consumer(int id);//消费者
int main(int argc,char **argv)
{
if(pipe(pipe_fd)<0) //pipe()返回值小于0则创建管道不成功
{
printf("pipe create error.\n");
exit(-1);
}
else //创建管道成功
{
printf("pipe is created successfully!\n");
if((pid1=fork())==0) // 子进程执行,父进程不执行,但是子进程中有exit(id)
producer(1);
if((pid2=fork())==0) // 子进程执行,父进程不执行,但是子进程中有exit(id)
producer(2);
if((pid3=fork())==0) // 子进程执行,父进程不执行,但是子进程中有exit(id)
consumer(1);
if((pid4=fork())==0) // 子进程执行,父进程不执行,但是子进程中有exit(id)
consumer(2);
}
close(pipe_fd[0]); //关闭管道读操作
close(pipe_fd[1]); //关闭管道写操作
int i,pid,status;
for(i=0;i<4;i++)
pid=wait(&status);//表示父进程关心子进程的完成情况,如果子进程完成了则返回值给父进程
exit(0);
}
int producer(int id)
{
printf("producer %d is running!\n",id);//生产者id正在生产
close(pipe_fd[0]); //关闭管道读操作
int i=0;
for(i=1;i<10;i++) //每个生产者可以生产9次产品
{
sleep(3); //暂停三秒
if(id==1) //生产者1生产aaa
strcpy(w_buf,"aaa\0");
else //生产者2生产bbb
strcpy(w_buf,"bbb\0");
if(write(pipe_fd[1],w_buf,4)==-1) //将w_buf中写4个字符道管道中,等于-1,则写到管道出错
printf("write to pipe error\n");
}
close(pipe_fd[1]); //关闭管道写操作
printf("producer %d is over!\n",id);//生产者id已经生产完毕
exit(id);//子进程退出
}
int consumer(int id)
{
close(pipe_fd[1]); //关闭管道写操作
printf("consumer %d is running!\n",id);//消费者id正在消费
if(id==1) //消费者1消费ccc
strcpy(w_buf,"ccc\0");
else //消费者2消费ddd
strcpy(w_buf,"ddd\0");
while(1)
{
sleep(1); //暂停1秒
strcpy(r_buf,"eee\0"); //将r_buf赋值为eee
if(read(pipe_fd[0],r_buf,4)==0) //从管道中读出4个字符给r_buf,如果等于0,则表示管道中已经没东西了,也就是说明此时管道中没有生产品,因此消费者没办法消费,就直接退出
break;
printf("consumer %d get %s,while the w_buf is %s\n",id,r_buf,w_buf);
}
close(pipe_fd[0]); //关闭管道读操作
printf("consumer %d is over!\n",id); //消费者id已经消费完
exit(id);//子进程退出
}
#include "sched.h"
#include "pthread.h"
#include "stdio.h"
#include "stdlib.h"
#include "semaphore.h"
#include "pthread.h"//Linux系统下的多线程遵循POSIX线程接口,称为pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。
int producer(void *args);
int consumer(void *args);
pthread_mutex_t mutex;//互斥锁
sem_t product;
sem_t warehouse;
char buffer[8][4];//0~7个4个字节的缓冲区
int bp=0;//bp初始化
main(int argc,char **argv)
{
pthread_mutex_init(&mutex,NULL);//将mutex初始化为
sem_init(&product,0,0); //将product初始化为0
sem_init(&warehouse,0,8); //将warehouse初始化为8;
int clone_flag,arg,retval;
char *stack;
clone_flag=CLONE_VM|CLONE_SIGHAND|CLONE_FS|CLONE_FILES;//书本上有错误,CLONE_SIGNAND应修改为CLONE_SIGHAND
int i;
for(i=0;i<2;i++) //创建四个线程
{
arg=i;
stack=(char *)malloc(4096);//分配栈
retval=clone((void *)producer,&(stack[4095]),clone_flag,(void *)&arg);
//调用producer(void *arg)函数
stack=(char *)malloc(4096);//分配栈
retval=clone((void *)consumer,&(stack[4095]),clone_flag,(void *)&arg);
//调用consumer(void *arg)函数
}
exit(1);
}
int producer(void *args)
{
int id=*((int *)args); //给id赋值
int i;
for(i=0;i<10;i++) //每个生产者可以生产10次产品
{
sleep(i+1); //暂停i+1秒
sem_wait(&warehouse);
//执行p操作,将warehouse减去1,说明空间减少了1。如果warehouse小于0,则说明空间已满,不能在生产
pthread_mutex_locl=k(&mutex);//加锁,此时消费者不能消费,实现互斥
if(id==0) //生产者1生产aaa
strcpy(buffer[bp],"aaa\0");
else //生产者2生产bbb
strcpy(buffer[bp],"bbb\0");
bp++; //buffer的地址加1,指向下一个地址
printf("producer %d produce %s in %d\n",id,buffer[bp-1],bp-1);//书本上此处有错误,如果按照书本的算法,就不能得出正确的结果,需要修改bp的值才能得出正确结果,验证的话只要带入具体的对应数据即可
pthread_mutex_unlock(&mutex);//解锁,此时生产者生产一件产品结束,解除互斥,消费者可以消费
sem_post(&product); //执行v操作,将product加1,说明产品增加一件
}
printf("producer %d is over!\n",id);//生产者生产完毕
}
int consumer(void *args)
{
int id=*((int *)args); //给id赋值
int i;
for(i=0;i<10;i++) //每个消费者消费10次
{
sleep(10-i); //暂停10-i秒
sem_wait(&product);
//执行p操作,将product减去1,说明产品减少了一件。如果product小于0,则说明没有产品,不能消费
pthread_mutex_locl=k(&mutex);//加锁,此时生产者不能生产,实现互斥
bp--; //buffer的地址减1,指向上一个地址
printf("consumer %d get %s in %d\n",id,buffer[bp],bp);//书本上此处有错误,如果按照书本的算法,就不能得出正确的结果,需要修改bp的值才能得出正确结果,验证的话只要带入具体的对应数据即可
strcpy(buffer[bp],"zzz\0");
pthread_mutex_unlock(&mutex);//解锁,此时消费者消费一件产品结束,解除互斥,生产者可以生产
sem_post(&warehouse); //执行v操作,将warehouse加1,说明空间增加1
}
printf("consumer %d is over!\n",id);
}

synthia0592
- 粉丝: 0
- 资源: 3
评论0