linux进程与线程通讯实验报告.docx
《linux进程与线程通讯实验报告.docx》由会员分享,可在线阅读,更多相关《linux进程与线程通讯实验报告.docx(10页珍藏版)》请在冰豆网上搜索。
linux进程与线程通讯实验报告
标。
linux进程与线程通讯实验报告
操作系统实验一进程与线程—Linux进程与线程通讯实验报告
操作系统课程设计任务书
篇二:
操作系统实验Linux进程与线程通讯
Linux进程与线程通讯
报告人:
设计目的
1、深刻理解线程和进程的概念
2、掌握线程与进程在组成成分上的差别以及与其相适应的通讯方式和应用目
设计的内容
1、以Linux系统进程和线程机制为背景,掌握fork()和clone()系统调用的
2、形式和功能以及与其相适应的高级通讯方式。
由fork派生的子进程之间
通过
pipe通讯,由clone创建的线程之间通过共享内存通讯,对于后者需要考虑互
斥问题。
3、以生产者-消费者问题为例,通过实验理解fork()和clone()两个系统调
的区别。
程序要求能够创建4个进程或线程,其中包括两个生
产者和两个消费者,生产者和消费者之间能够传递数据。
设计准备
1、fork系统调用、
pid=fork()
创建一个子进程,子进程是父进程的完整复制,正常返回值为非负整数,对于父进程来说该数大于0,是子进程的编号(pid);对于子进程来说该数为0。
正是利
用反回值的差别可以决定二者不同的后继动作。
2、clone系统调用
intclone(int(*fn)(void*arg),void*stack,intflags,void*arg);
其中fn是轻进程所执行的函数,stack是轻进程所使用的栈,flag是
CLONE_VM,CLONE_FS,CLONE_FILES,
LONE_SIGHAND,CLONE_的组合,arg是调用过程的对应参数。
Clone()的关
键是flag的设定,CLONE_VS示子进程共享父进程内存,CLONE_F表示子进程共
进程共享父进程的消息处理机制,
CLONE_PI是指子进程继承父进程的id号。
3、pipe系统调用
et_val=pipe(fd);
fork创建的子进
参数定义为intfd[2]。
创建一个管道文件,返回两个文件描述符fd[0]和
fd[1]分别用于管道文件的读和写操作。
管道文件创建后,可以被程共享。
4、sem_wait(&s)和sem_post(&s)分别相当于信号灯的P操作和V操作。
其中s是说明
为sem_t类型的信号灯。
初始化函数sem_init(s,0,8)
5、pthread_mutex_lock(&mutex)和pthread_mutex_unlock(&mutex)
分别用于加锁和解锁。
参数为pthread_mutex_tmutex定义的互斥锁。
初始化
tthread_mutex_init(&mutex,NULL)
四、实验设计
2、
然后用fork()创建两个生产进程和两个消费进程
7、
利用pthread_mutex_lock(),pthread_mutex_unlock()等函数实现对共享
存储区访问的互斥
分析结果:
由程序
(1)结果可见,当一个进程改变其空间数据时,其他进程空间对应数据内容并未改变,说明在使用fork()语句创建的子进程与其父进程具有相对独立的地址空间,在解决生产消费的问题时,可以采用pipe()进行通信。
因为子进程复制了父进程的打开文件表,所以pipe()所建立的通信管道可被子进程继承,生产和消费进程可以通过对同一管道文件的读写进行通讯。
程序
(1)中,消费者从管道中接收生产者发送的数据,并且和自己存储区中的数据进行比较,两者的数据是不同的,说明两个进程拥有不同的存储空间。
2、基于clone()的结果输出
分析结论:
由程序
(2)结果可见,clone()语句在创建进程时,可通过参数设定子进程与父进程是否共享存储空间,从而可以创建真正意义上的线程。
生产者和消费者进程共享内存,从而可以通过共享内存直接交换数据。
但是多个进程共享内存需要互斥机制,程序中定义了临界区变量mutex和两个信号量Product,warehouse,临界区
变量用于共享内存操作的互斥,信号量分别实现了生产者和消费者的等待。
程序
(2)中,消费者输出存储区中的数据,并且存储区中的数
据随着生产者存入的数据而发生变化,说明clone()语句通过flag的设定实现了共享内存。
若在实验中除去CLONE_Va项,将出现非预期的结果。
篇三:
操作系统实验报告_进程和线程
计算机科学与软件学院
操作系统上机实验报告
学生姓名:
学号:
班级:
班实验日期:
2014.4.17
实验名称:
进程和线程
实验目的:
理解unix/Linux下进程和线程的创建、并发执行过程。
实验内容:
1(进程的创建
2(多线程应用
实验步骤及分析:
(此部分为关键内容:
要求整理实验主要步骤,总结编写实验
过程中遇到哪些问题,如何解决的,若未解决也应总结,回答思考题的答案)
、进程的创建
F面这个C程序展示了UNIX系统中父进程创建子进程及各自分开活动的情
况。
1、实验指导
fork()
创建一个新进程。
系统调用格式:
pid=fork()
参数定义:
intfork()
fork()返回值意义如下:
0:
在子进程中,pid变量保存的fork()返回值为0,表示当前进程是子进程。
0:
在父进程中,pid变量保存的fork()返回值为子进程的id值(进程唯一标识符)。
-1:
创建失败。
如果fork()调用成功,它向父进程返回子进程的PID,并向子进程返回0,即fork()被调用了一次,但返回了两次。
此时OS在内存中建立一个新进程,所建的
新进程是调用fork()父进程(parentprocess)的副本,称为子进程(childprocess)。
子进程继承了父进程的许多特性,并具有与父进程完全相同的用户级上下文。
父进程与子进程并发执行。
2、参考程序代码
/*process.c*/
#includestdio.h
#includesys/types.h
main(intargc,char*argv[])
intpid;
/*forkanotherprocess*/
pid=fork();
if(pid0){/*erroroccurred*/
fprintf(stderr,ForkFailed);
exit(-1);
elseif(pid==0){/*childprocess*/
execlp(/bin/ls,ls,NULL);
else{/*parentprocess*/
/*parentwillwaitforthechildtocomplete*/
wait(NULL);
printf(ChildComplete);
exit(0);
3、编译和运行
$gccprocess.c-oprocesss
4、运行
$./process程序运行截图
(2)
扩展程序,在父进程中输出1到5,在子进程中输出6-10,要求父子进程
并发
输出;记录实验结果,并给出简单分析。
6.实验中遇到的问题和解决方法
、多线程应用
编写unix/Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。
下面是一个最简单的多线程程序example1.c。
1.实验指导
面的示例中,要使用到两个函数,pthread_create和pthread_join,并声
明了一个pthread_t型的变量。
函数pthread_create用来创建一个线程,它的原型为:
externintpthread_create__P((pthread_t*__thread,__const
pthread_attr_t*__attr,void*(*__start_routine)(void*),void
*__arg));
第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。
这里,我们的函数thread不需要参数,所以最后一个参数设为空指针。
第二个参数我们也设为
空指针,这样将生成默认属性的线程。
当创建线程成功时,函数返回0,若不为0
则说明创建线程失败,常见的错误返回代码为EAGAINffiEINVAL前者表示系统限
制创建新的线程,例如线程数目过多了
后者表示第二个参数代表的线程属性值非法。
创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。
函数pthread_join用来等待一个线程的结束。
函数原型为:
externintpthread_join__P((pthread_t__th,void
第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等
待的线程结束为止,当函数返回时,被等待线程的资源被收回。
一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现。
它的函数原型为:
externvoidpthread_exit
P((void*__retval))__attribute__((__noreturn__));
唯一的参数是函数的返回代码,只要pthread_join中的第二个参数
thread_return不是NULL,这个值将被传递给thread_return
2、参考程序代码
/*thread.c*/
#includestdio.h
#includepthread.h
voidthread(void)
inti;
for(i=0;i3;i++)
printf(Thisisapthread.\n);
intmain(intargc,char*argv[])
inti,ret;
ret=pthread_create(&id,NULL,(void*)thread,NULL);
if(ret!
=0){
printf(Createpthreaderror!
\n);
exit
(1);
for(i=0;i3;i++)
printf(Thisisthemainprocess.\n);
pthread_join(id,NULL);
return(0);
3、编译和运行
编译此程序:
gccexample1.c-lpthread-oexample1
-lpthread:
使用线程库
运行example1,得到如下结果:
Thisisthemainprocess.
Thisisapthread.
Thisisthemainprocess.
Thisisthemainprocess.
Thisisapthread.
Thisisapthread.
再次运行,可能得到如下结果:
Thisisthemainprocess.
Thisisapthread.
Thisisthemainprocess.
Thisisapthread.
Thisisthemainprocess.
程序运行截图
4、思考
(1)程序运行后,进程thread中有几个线程存在,
(2)为什么前后两次运行结果不一样,答
(1)
(2)
5.实验中遇到的问题和解决方法
运行结果并没有出现预期效果