Linux下创建进程线程以及通信技术的使用

网友投稿 253 2022-10-17


Linux下创建进程线程以及通信技术的使用

一、实验目的

学习使用Linux的系统调用和pthread线程库编写程序,进一步理解、掌握操作系统进程、线程概念,利用信号量解决进程同步与互斥。

二、实验内容

1.         Fibonacci序列是0, 1, 1, 2, 3, 5, 8, .... ,通常它可以表示为:

f ib0 = 0

f ib1 = 1

f ibn = f ibn−1 + f ibn−2

编写一个C程序,使用系统调用fork()创建两个子进程P1和P2。他们的任务如下:

1)        子进程P1打印自己的pid,然后使用exec(族)系统调用显示当前目录下文件和子目录的详细信息。

2)        子进程P2中生成Fibonacci序列,序列的个数在程序命令行中作为参数传入,例如,参数为7,则子进程P2生成的Fibonacci序列为0、1、2、3、5、8、13。通过某种进程通信机制(共享内存、管道、消息等IPC机制),子进程P2把生成的Fibonacci序列发送给父进程,并由父进程输出(打印)Fibonacci序列。在父子进程通信的过程中必须实现同步,以使在子进程完成生成序列之前,父进程不会输出Fibonacci序列。使用wait()系统调用可以实现各进程的同步。执行必要的错误检查以保证不会接受命令行参数传递来的负值。

2.         编写程序实现生产者-消费者问题。使用linux的Pthread线程库,创建2个生产者线程和2个消费者线程。生产者线程计算当前的时间,把时间、第几次计算时间的序号(循环次数)和线程ID作为一个消息,把消息放入缓冲区,消费者线程从缓冲区读出一个消息并显示消息。缓冲区大小为5个,每个生产者线程生产10个消息,每个消费者线程消费10个消息,即生产和消费分别为20次。

生产者及消费者线程之间需要实现同步和互斥,Pthread线程库的信号量机制可以完成这一任务。

三、源代码

(1)

#include #include #include //定义管道的最大值 #define MAXLINE 80 //覅波那次函数 int fibonaci(int n) {     if(n==0) return 0;     else if(n==1) return 1;     else         return fibonaci(n-2)+fibonaci(n-1); } //main主函数 void main(int argc,char* argv[]) {     pid_t pid1; //子进程p1的id     pid_t pid2; //子进程p2的id     int fd[2];     int k=0;     int line[MAXLINE];     for(k;k=1)             {                 line[number]=fibonaci(number-1);                 number=number-1;             }             //把数组写入到管道             close(fd[0]);             write(fd[1],line,MAXLINE);         }         else         {             wait(NULL); //wait for pid1             wait(NULL); //wait for pid2             close(fd[1]);             read(fd[0],line,MAXLINE);             printf("The fibonaci array is as follows:\n ");             int m=1;             while(line[m]!=-1)             {                            printf("%d ",line[m]);                 m=m+1;             }             printf("\n");         }     }     close(fd[0]);     close(fd[1]);     //return 0; }     (2)

#include #include #include #include #include #include sem_t sem1,sem2; //信号量    pthread_mutex_t mutex1,mutex2; //互斥量 //定义缓冲区结构 struct container_buffer {     //线程号     pid_t id;     //读取序号     int number;     //时间     time_t mytime; }*p,*r,*w; //定义3个结构指针 /*函数write1,2,用于生产者计算当前的时间,把时间、第几次计算时间的序号 (循环次数)和线程ID作为一个消息,把消息放入缓冲区 */ void *write1(void *arg) {     //生产10个消息     int i=1;     for(i;i<=10;i++)     {         //if(w==p+5)w=p;         sem_wait(&sem1); //缓冲减1         pthread_mutex_lock(&mutex1); //加锁         w->number=i;         w->id=pthread_self();         time(&(w->mytime));         w++;         sem_post(&sem2); //可读加1         pthread_mutex_unlock(&mutex1); //解锁         sleep(1+(int)(5*rand()/(RAND_MAX+1.0))); //随机睡觉x秒,1<=x<=5     }    } void *write2(void *arg) {     //生产10个消息     int j=1;     for(j;j<=10;j++)     {         //if(w==p+5)w=p;         sem_wait(&sem1);         pthread_mutex_lock(&mutex1);         w->number=j;         w->id=pthread_self();         time(&(w->mytime));         w++;         sem_post(&sem2);         pthread_mutex_unlock(&mutex1);         sleep(1+(int)(5*rand()/(RAND_MAX+1.0)));     } } /*函数read1,2,用于消费者从缓冲区读出一个消息并显示消息 */ void *read1(void *arg) {     //消费10个消息     int k=1;     for(k;k<=10;k++)     {         //if(r==p+5)r=p;         sem_wait(&sem2); //可读减1         pthread_mutex_lock(&mutex2); //加锁         printf("消费者1第%d次读取消息---, id=%u, time is: %s\n",r->number,(unsigned)(r->id),ctime(&(r->mytime)));         r++;         sem_post(&sem1); //缓冲加1         pthread_mutex_unlock(&mutex2); //解锁         sleep(1+(int)(5*rand()/(RAND_MAX+1.0))); ////随机睡觉x秒,1<=x<=5     } } void *read2(void *arg) {     //消费10个消息     int l=1;     for(l;l<=10;l++)     {         //if(r==p+5)r=p;         sem_wait(&sem2);         pthread_mutex_lock(&mutex2);         printf("消费者2第%d次读取消息---, id=%u, time is: %s\n",r->number,(unsigned)(r->id),ctime(&(r->mytime)));         r++;         sem_post(&sem1);         pthread_mutex_unlock(&mutex2);         sleep(1+(int)(5*rand()/(RAND_MAX+1.0)));     } } void main() {     pthread_t pro1,pro2;//生产者     pthread_t cum1,cum2;//消费者         sem_init(&sem1,0,5); //创建初始值为5的信号量     sem_init(&sem2,0,0); //创建初始值为0的信号量     pthread_mutex_init(&mutex1,NULL);     pthread_mutex_init(&mutex2,NULL);     p=(struct container_buffer*)malloc(20*sizeof(struct container_buffer));    //申请20个结构内存空间     r=p;     w=p;     //创建2个生产者线程和2个消费者线程     pthread_create(&pro1,NULL,write1,NULL);     pthread_create(&pro2,NULL,write2,NULL);     pthread_create(&cum1,NULL,read1,NULL);     pthread_create(&cum2,NULL,read2,NULL);     //互斥量销毁     pthread_mutex_destroy(&mutex1);     pthread_mutex_destroy(&mutex2);     //线程挂起     pthread_join(pro1,NULL);     pthread_join(pro2,NULL);     pthread_join(cum1,NULL);     pthread_join(cum2,NULL);         //释放内存     free(p);     return; }


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:关于即时通信技术选择的一点浅见
下一篇:feign调用返回object类型转换方式
相关文章

 发表评论

暂时没有评论,来抢沙发吧~