linux进程和线程通信.docx
- 文档编号:24223740
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:15
- 大小:668.68KB
linux进程和线程通信.docx
《linux进程和线程通信.docx》由会员分享,可在线阅读,更多相关《linux进程和线程通信.docx(15页珍藏版)》请在冰豆网上搜索。
linux进程和线程通信
课程设计
课程设计名称:
linux进程和线程通讯
专业班级:
学生姓名:
学号:
指导教师:
课程设计时间:
计算机科学与技术专业课程设计任务书
学生姓名
专业班级
学号
题目
Linux进程和线程通讯
课题性质
其它
课题来源
自拟课题
指导教师
同组姓名
无
主要内容
1.以Linux系统进程和线程机制为背景,掌握fork()和clone()系统调用的形式和功能以及与其相适应的高级通信方式。
由fork派生的子进程之间通过pipe通信,由clone创建的线程之间通过共享内存通信。
2.以生产者-消费者为例,通过实验理解fork和clone两个系统调用的区别。
程序要求能够创建4个进程或线程,其中包括两个生产者和两个消费者,生产者和消费者之间能够传递数据。
任务要求
1.深刻理解线程和进程的概念,
2.掌握线程和进程在组成成分上的差别以及与其相适应的通信方式和应用目标。
参考文献
[1]张尧学,史美林.计算机操作系统教程.北京:
清华大学出版社,2000
[2]孟庆昌.操作系统教程.北京:
电子工业出版社,2004
[3]GaryNutt.操作系统现代观点.孟祥由译.北京:
机械工业出版社,2004
[4]陈向群,杨芙清.操作系统教程.2版.北京:
北京大学出版社,2006
[5]汤小丹.计算机操作系统第三版.西安:
西安电子科技大学出版社,2007
审查意见
指导教师签字:
教研室主任签字:
年月日
说明:
本表由指导教师填写,由教研室主任审核后下达给选题学生,装订在设计(论文)首页
1需求分析
深刻理解线程和进程的概念,掌握线程和进程在组成成分上的差别以及与其相适应的通信方式和应用目标。
此次课程设计以Linux系统进程和线程机制为背景,掌握fork()和clone()系统调用的形式和功能以及与其相适应的高级通信方式。
由fork派生的子进程之间通过pipe通信,由clone创建的线程之间通过共享内存通信。
以生产者-消费者为例,通过实验理解fork和clone两个系统调用的区别。
程序要求能够创建4个进程或线程,其中包括两个生产者和两个消费者,生产者和消费者之间能够传递数据。
2概要设计
进程是系统分配资源的基本单位,是一个具有独立功能的程序段对某个数据集的一次执行活动。
进程具有动态性,并发性等特点。
反映进程动态特性的是进程状态的变化。
进程要经历创建,等待资源,就绪准备执行,以及执行前和执行后释放资源小王等几个过程和状态。
进程的状态转换要有不同的原语句执行完成。
进程的并分特性反映在进程对资源的竞争以及有资源竞争所引起的对进程执行速度的制约。
这种制约可分为直接制约和间接制约。
进程间的直接制约是被制约进程和制约进程之间,存在着对方资源的需求,只有制约进程执行后,被制约进程才能继续往前推进。
进程间的间接制约是被制约进程共享某个一次只能供一个进程使用的系统资源,只有得到资源的进程才能向前推进,其他进程在获得资源进程执行期间不允许交叉执行,因此直接制约进程之间具有固定的执行顺序,而间接制约的进程之间则没有固定的执行顺序。
线程是为了提高操作系统的执行效率而引入的,它是进程内的一段程序的基本调度单元。
线程可分为用户级线程和系统级线程。
用户级线程的管理全部由线程库完成,与操作系统内核无关,线程有寄存器,堆栈以及程序计数器等组成,同意进程的线程共享该进程的进程空间和其他所有资源。
线程主要用于多级系统以及网络系统的操作系统中,
Linux系统中的fork()保持了unix大的经典语义,被创建的进程具有独立于独立于父进程的地址空间,二者之间的通讯通常可采用pipe机制。
Clone()是linux系统特有的系统调用,可以通过参数确定父子进程之间是否共享空间资源,在地址空间等资源共享等情况下,clone实质是哪个相当于创建了一个轻进程或线程,这是clone的通常用法。
实际上在linux系统中,fork以及用户线程pthread都是基于clone实现的。
有fork派生出的子进程之间通过pipe通讯,由clone创建的线程之间通过共享内存通讯,对于后者需要考虑互斥问题。
Fork()系统 用pipe()创建一个管道文件,然后用fork()创建两个生产进程和两个消费进程,它们之间通过pipe()传递信息。
Clone()系统用clone()创建四个轻进程(线程),用参数指明共享内存等资源,通过共享内存模拟生产消费问题,利用pthread_mutex_lock(),pthread_mutex_unlock()等函数实现对共享存储区访问的互斥
fork()系统调用流程图:
Y
N
Y
N
clone()系统调用流程图:
YY
3运行环境
硬件环境:
AMD速龙双核250处理器,主频3.0GHZ,320G硬盘,2G内存,
软件环境:
ubuntu12.04版本
4开发工具和编程语言
linux系统下自带c语言编译工具
5详细设计
(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,CLONE_SIGHAND,CLONE_PID的组合,arg是调用过程的对应参数。
Clone()的关键是flag的设定,CLONE_VM表示子进程共享父进程内存,CLONE_FS表示子进程共享父进程的文件系统,CLONE_SIGHAND表示子进程共享父进程的消息处理机制,CLONE_PID是指子进程继承父进程的id号。
(3) pipe系统调用ret_val=pipe(fd);
参数定义为intfd[2]。
创建一个管道文件,返回两个文件描述符fd[0]和fd[1]分别用于管道文件的读和写操作。
管道文件创建后,可以被fork创建的子进程共享。
(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)。
Fork()系统主程序:
#include
#include
#include
#include
#include
#include
#include
#include
#include
charr_buf[4];//读缓冲
charw_buf[4];//写缓冲
intpipe_fd[2];
pid_tpid1,pid2,pid3,pid4;
intproducer(intid);
intconsumer(intid);
intmain(intargc,char**argv)
{
if(pipe(pipe_fd)<0)
{
printf("pipecreateerror.\n");
exit(-1);
}
else
{
printf("pipeiscreatesuccessfully!
\n");
if((pid1=fork())==0)
producer
(1);
if((pid2=fork())==0)
producer
(2);
if((pid3=fork())==0)
consumer
(1);
if((pid4=fork())==0)
consumer
(2);
}
close(pipe_fd[0]);//需要加上这两句,否则会有读者或写者永远等
close(pipe_fd[1]);
inti,pid,status;
for(i=0;i<4;i++)
pid=wait(&status);
exit(0);
}
intproducer(intid)
{
printf("producer%disrunning\n",id);
close(pipe_fd[0]);
inti=0;
for(i=1;i<10;i++)
{
sleep(3);
if(id==1)//生产者1
strcpy(w_buf,"aaa\0");
else//生产者2
strcpy(w_buf,"bbb\0");
if(write(pipe_fd[1],w_buf,4)==-1)
printf("writetopipeerror\n");
}
close(pipe_fd[1]);
printf("producer%disover\n",id);
exit(id);
}
intconsumer(intid)
{
close(pipe_fd[1]);
printf("consumer%disrunning!
\n",id);
if(id==1)//消费者1
strcpy(w_buf,"ccc\0");
else//消费者2
strcpy(w_buf,"ddd\0");
while
(1)
{
sleep
(1);
strcpy(r_buf,"eee\0");
if(read(pipe_fd[0],r_buf,4)==0)
break;
printf("consumer%dget%s,whilethew_bufis%s\n",id,r_buf,w_buf);
}
close(pipe_fd[0]);
printf("consumer%disover!
\n",id);
exit(id);
}
Clone()系统主程序:
#include
#include
#include
#include
#include
#include
#include
#include
#include
intproducer(void*args);
intconsumer(void*args);
pthread_mutex_tmutex;
sem_tproduct;
sem_twarehouse;
charbuffer[8][4];
intbp=0;
main(intargc,char**argv)
{
pthread_mutex_init(&mutex,NULL);
sem_init(&producer,0,0);
sem_init(&warehouse,0,8);
intclone_flag,arg,retval;
char*stack;
clone_flag=CLONE_VM|CLONE_SIGNAND|CLONE_FS|CLONE_FILES;
inti;
for(i=0;i<2;i++)
{//创建四个线程
arg=i;
stack=(char*)malloc(4096);
retval=clone((void*)producer,&(stack[4095]),clone_flag,(void*)&arg);
stack=(char*)malloc(4096);
retval=clone((void*)consumer,&(stack[4095]),clone_flag,(void*)&arg);
}
exit
(1);
}
intproducer(void*args)
{
intid=*((int*)args);
inti;
for(i=0;i<10;i++)
{
sleep(i+1);//表现线程速度差别
sem_wait(&warehouse);
pthread_mutex_lock(&mutex);
if(id==0)
strcpy(buffer[bp],"aaa\0");
else
strcpy(buffer[bp],"bbb\0");
bp++;
printf("producer%dproduce%sin%d\n",id,buffer[bp],bp-1);
pthread_mutex_unlock(&mutex);
sem_post(&product);
}
printf("producer%disover!
\n",id);
}
intconsumer(void*args)
{
intid=*((int*)args);
inti;
for(i=0;i<10;i++)
{
sleep(10-i);//表现线程速度差别
sem_wait(&product);
pthread_mutex_lock(&mutex);
bp--;
printf("consumer%dget%sin%d\n",id,buffer[bp],bp+1);
strcpy(buffer[bp],"zzz\0");
pthread_mutex_unlock(&mutex);
sem_post(&warehouse);
}
printf("consumer%dget%sisover!
\n",id);
}
6调试分析
在fork()系统调用中,消费者从管道中接收生产者的数据,并且将其和自己的存储区中的数据进行比较,两者数据不同,说明两个进程拥有不同的存储空间。
在clone系统调用中,消费者输出存储区的数据,并且存储区的数据随着生产者存入的数据而发生变化,说明clone()语句通过flag的设定实现了共享内存,如在实验中出去clone_vm选项,将出现非预期的结果。
7测试结果
图1,基于fork()的输出
图2基于clone()输出
参考文献
[1]张尧学,史美林.计算机操作系统教程.北京:
清华大学出版社,2000
[2]孟庆昌.操作系统教程.北京:
电子工业出版社,2004
[3]GaryNutt.操作系统现代观点.孟祥由译.北京:
机械工业出版社,2004
[4]陈向群,杨芙清.操作系统教程.2版.北京:
北京大学出版社,2006
[5]汤小丹.计算机操作系统第三版.西安:
西安电子科技大学出版社,2007
心得体会
经过两个星期的不懈努力,操作系统课程设计终于完成了。
在完成课程设计的过程中,深深明白了打好基础的重要性,不过还好在老师和同学的帮助下终于按时完成了。
在这次实验的过程中我觉得应该从一下几个方面努力:
1.努力学好编程基础知识,这样当碰到问题时可以更大限度的发散自己的思维,来寻求解决问题的办法,而不必在麻烦其他同学,毕竟现在已经是大三,都在忙着学习。
2.努力提高自己分析问题的能力,俗话说万变不离其宗,我们不仅要学会做题,还要讲究会做,重在学会一种解题方法,这样当碰到新题目时才不会束手无策。
3.增加对毅力的锻炼,冰冻三尺,非一日之寒,在学习上不能断断续续,而应当持之以恒,当碰到难题时,一定要先独立思考,只有这样才能提高。
4.以后多加细心,编程讲究的是细心,在写好代码后细心检查,也许是只是一个符号的问题,就会导致运行的错误。
此次课程设计让我受益匪浅,今后力争在以上几个方面多加改进,力求更上一层楼!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 进程 线程 通信