linux 下怎么创建线程,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

line[k]=-1;

pipe(fd);

pid1=fork();

if(pid1<0)

{

printf("error fork\n");

exit(1);

}

else if(pid1==0) //子进程1

{

//显示当前目录的文件信息

printf("The current content is as follows:\n");

execlp("/bin/ls","ls",NULL);

}

else //父进程

{

//继续产生子进程2

pid2=fork();

if(pid2<0)

{

printf("error fork\n");

exit(0);

}

else if(pid2==0) //子进程2

{

int number=atoi(argv[1]); //通过命令行参数得到斐波那契数组的参数

if(number<0)number=-number; //error correct

//调用fibonaci函数

while(number>=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; }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值