管道通信(线程、进程)
**设有二元函数 f(x,y) = f(x) + f(y)
其中:
• f(x)=1 (x=1)
• f(x) = f(x-1) * x (x >1)
• f(y)=1 (y=1,2)
• f(y) = f(y-1) + f(y-2) (y> 2)
请基于无名管道,利用 pthread 线程库编程建立 3 个并发协作线程,它们分别完成 f(x,y)、f(x)、f(y)
**
/*
Function: 利用管道实现在在线程间传递整数
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
void task1(int *); // 线程 1 执行函数原型
void task2(int *); // 线程 2 执行函数原型
void task3(int *);//thrd3
int pipe1[2],pipe2[2]; // 存放第两个无名管道标号
pthread_t thrd1,thrd2,thrd3; // 存放第两个线程标识
int x,y;//a<50
int main(int argc,char *arg[])
{
scanf("%d %d",&x,&y);
//printf("%d\n",y);
int ret;
int num1,num2,num3;
// 使用 pipe() 系统调用建立两个无名管道。建立不成功程序退出,执行终止
if(pipe(pipe1) < 0)
{
perror("pipe1 not create");
exit(EXIT_FAILURE);
}
if(pipe(pipe2) < 0)
{
perror("pipe2 not create");
exit(EXIT_FAILURE);
}
// 使用 pthread_create 系统调用建立两个线程。建立不成功程序退出,执行终止
num1 = 1 ;
ret = pthread_create(&thrd1,NULL,(void *) task1,(void *) &num1);
if(ret)
{
perror("pthread_create: task1");
exit(EXIT_FAILURE);
}
num2 = 2 ;
ret = pthread_create(&thrd2,NULL,(void *) task2,(void *) &num2);
if(ret)
{
perror("pthread_create: task2");
exit(EXIT_FAILURE);
}
num3 = 3 ;
ret = pthread_create(&thrd3,NULL,(void *) task3,(void *) &num3);
if(ret)
{
perror("pthread_create: task3");
exit(EXIT_FAILURE);
}
// 挂起当前线程,等待线程 thrd3 结束,并回收其资源
pthread_join(thrd2,NULL);
pthread_join(thrd3,NULL);
pthread_join(thrd1,NULL);
exit(EXIT_SUCCESS);
}
// 线程 1 执行函数,它首先向管道 1 写,然后从管道 2 读
void task3(int *num)//get f(x)
{
int i=1;
int f[50];
f[1]=1;
for(i=2;i<=x;i++)
{
f[i]=f[i-1]*i;
}
write(pipe1[1],&f[x],sizeof(int));
printf("thread3 write: %d\n",f[x]);
//read(pipe2[0],&x,sizeof(int));
// 读写完成后 , 关闭管道
close(pipe1[1]);
//close(pipe2[0]);
}
// 线程 2 执行函数,它首先从管道 1 读,然后向管道 2 写
void task2(int * num)//g[y]
{
int j;
int g[50];
g[1]=1;
g[2]=1;
for(j=3;j<=y;j++)
{
g[j]=g[j-1]+g[j-2];
}
write(pipe2[1],&g[y],sizeof(int));
printf("thread2 write: %d\n",g[y]);
// 读写完成后 , 关闭管道
//close(pipe1[0]);
close(pipe2[1]);
}
void task1(int *num)
{
int f,g;
read(pipe1[0],&f,sizeof(int));
printf("thread1 read: %d\n",f);
read(pipe2[0],&g,sizeof(int));
printf("thread1 read: %d\n",g);
close(pipe1[0]);
close(pipe2[0]);
printf("%d\n",f+g);
}
src = test2.c
obj = test2.o
opt = -g -c
all: test2
test2: $(obj)
gcc $(obj) -l pthread -o test2
test2.o: $(src)
gcc $(opt) $(src)
clean:
rm test2*.o