当前位置:文档之家› 进程实验-进程间通信(管道、消息、共享内存、软中断)

进程实验-进程间通信(管道、消息、共享内存、软中断)

进程实验-进程间通信(管道、消息、共享内存、软中断)
进程实验-进程间通信(管道、消息、共享内存、软中断)

进程实验3 Linux 进程间通信

一、软中断信号的处理,实现同一用户的各进程之间的通信。

●相关的系统调用

?kill(pid ,sig):发送信号

?signal(sig, func):指定进程对信号sig的处理行为是调用函数func。

●程序清单

#include

#include

#include

void waiting();

void stop();

int wait_mark;

main()

{

int p1,p2;

while((p1=fork())==-1);

if(p1>0)

{

while((p2=fork())==-1);

if(p2>0)

{ printf("parent\n");

/*父进程在此完成某个操作、或接收到用户从键盘输入的特殊按键命令后发出下面的信号。这里省略。*/

kill(p1,16);

kill(p2,17);

wait(0);

wait(0);

printf("parent process id killed! \n");

exit(0);

}

else/* p2==0*/

{

printf("p2\n");

wait_mark=1;

signal(17,stop);

waiting();

printf("child process 2 is killed by parent! \n");

exit(0);

}

}

else/*p1==0*/

{

printf("p1\n");

wait_mark=1;

signal(16,stop);

waiting();

printf("child process 1 is kelled by parent! \n");

exit(0);

}

}

void waiting()

{while(wait_mark!=0);}

void stop()

{wait_mark=0;}

●输入并运行此程序,分析程序的运行结果。

二、消息的创建、发送和接收

●多个进程通过访问一个公共的消息队列来交换信息

●消息队列: 即消息的一个链表

●任何进程都可以向消息队列中发送消息(消息类型及正文),其它进程都可以从消息

队列中根据类型获取相应的消息

●相关的系统调用头文件:#include

◆打开或创建消息队列:int msgget(key_t key, int msgflg);

●key:消息队列的键

?IPC_PRIV A TE: 创建一个私有的消息队列

?其它:可被多个进程使用的消息队列

●msgflg:设置操作类型及访问权限IPC_CREAT / IPC_EXCL

◆获得或设置消息队列属性:int msgctl( int msgid, int cmd, struct msqid_ds

*data);

◆发送消息:int msgsnd(int msgid, const void *msgp,

size_t msgsize, int flags);

●参数

?msgid:消息队列标识符id

?msgp:指针,用户自定义缓冲区,可定义成结构体类型,包含两项

long mtype;代表消息类型

char mtext[MTEXTSIZE];消息正文

?msgsize:要发送消息正文的长度

?mflags:标志,若设置IPC_NOW AIT则不等待

消息发出就返回

●返回值:成功返回0,错误返回-1(置errno)

◆接收消息int msgrcv(int msgid, void *msgp, size_t mtexsize, long msgtype,

int flags);

●参数:与msgsnd类似

◆msgtype

●>0:只接收指定类型消息的第一个

●==0:不管什么消息类型都读取队列中第一个数据

●<0:接收等于或小于其绝对值的最低类型的第一个,如有5、

6、17三类,若为-6,则获取类型5的。

●返回值

◆成功:返回消息正文字节数

◆错误:返回-1(置errno)

●程序清单

#include

#include

#include

#include

#define MSGKEY 75

struct msgform

{

long mtype;

char msgtext[1030];

}msg;

int msgqid,i;

void CLIENT()

{

int i; char string_i[5];

msgqid=msgget(MSGKEY,0777);

for(i=10;i>=1;i--)

{

msg.mtype=i;

printf("(client)sent\n");

sprintf(msg.msgtext,"the content of message ");

sprintf(string_i, "%d",i );

strcat(msg.msgtext,string_i);

strcat(msg.msgtext,"\n");

msgsnd(msgqid,&msg,1030,0);

}

exit(0);

}

void SERVER()

{

msgqid=msgget(MSGKEY,0777|IPC_CREAT);

do

{

msgrcv(msgqid,&msg,1030,0,0);

printf("(server)received message %d \n", msg.mtype );

printf(“%s\n", msg.msgtext );

}while(msg.mtype!=1);

msgctl(msgqid,IPC_RMID,0);

exit(0);

}

main()

{

while((i=fork())==-1);

if(!i) SERVER();

while((i=fork())==-1);

if(!i) CLIENT();

wait(0);

wait(0);

}

编辑并运行程序,并分析程序的运行结果。

思考题:符号常量MSGKEY有什么作用?server和client不使用同一个MSGKEY 会出现什么问题?

程序扩展:client和server之间怎样通过软中断信号控制进程的推进速度,使得client每发送一个消息,server就接收一个消息,然后client再发送下一个消息?

三、共享存储区的创建、发送和接收

同一系统中的几个进程可共享某块物理内存。include

●打开或创建创建共享区:int shmget(key_t key, size_t size, int shmflg);

?参数

◆key:键值

◆IPC_PRIV ATE: 创建一个私有的shm

◆其它:非IPC_PRIV ATE整数值。

◆size:指明shm的大小,若shm已经存在,则size应为0

◆shmflg:设置访问权限及IPC_CREAT / IPC_EXCL

◆返回值

●成功:该shm的id,当前进程是其拥有者及创建者

错误:-1

●将共享内存连接到进程中:void *shmat(int shmid, const void *shmaddr, int flags);

?参数

◆shmid:共享内存标识符id

◆shmaddr:进程映射内存段的地址,可指定,但一般设为NULL表示

由系统安排。

◆flags:对该内存的段设置是否只读(SHM_RDONLY),

默认是读写。

?返回值

◆成功:进程中该内存段的地址

◆错误:-1

程序清单:

#include

#include

#include

#include

#define SHMKEY 75

int shmid,i;

int *addr;

void CLIENT()

{

int i;

shmid=shmget(SHMKEY,1024,0777);

addr=shmat(shmid,0,0);

for(i=5;i>=0;i--)

{

while(*addr!=-1);

printf("(client)sent, ");

*addr=i;

printf("client i: %d\n",i);

}

exit(0);

}

void SERVER()

{

shmid=shmget(SHMKEY,1024,0777|IPC_CREAT);

addr=shmat(shmid,0,0);

do

{

*addr=-1;

while(*addr==-1);

printf("(server)received ," );

printf("server *addr %d\n", *addr);

}while(*addr);

shmctl(shmid,IPC_RMID,0);

exit(0);

}

main()

while((i=fork())==-1);

if(!i)SERVER();

while((i=fork())==-1);

if(!i) CLIENT();

wait(0);

wait(0);

}

编辑并运行程序,并分析程序的运行结果。

在此基础上对程序进行修改:使得每次循环中:CLIENT向共享区发送10个整数, SERVER从共享区接收10个整数、并输出。

Linux进程间通信(2)实验报告

实验六:Linux进程间通信(2)(4课时) 实验目的: 理解进程通信原理;掌握进程中信号量、共享内存、消息队列相关的函数的使用。实验原理: Linux下进程通信相关函数除上次实验所用的几个还有: 信号量 信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。要调用的第一个函数是semget,用以获得一个信号量ID。 int semget(key_t key, int nsems, int flag); key是IPC结构的关键字,flag将来决定是创建新的信号量集合,还是引用一个现有的信号量集合。nsems是该集合中的信号量数。如果是创建新集合(一般在服务器中),则必须指定nsems;如果是引用一个现有的信号量集合(一般在客户机中)则将nsems指定为0。 semctl函数用来对信号量进行操作。 int semctl(int semid, int semnum, int cmd, union semun arg); 不同的操作是通过cmd参数来实现的,在头文件sem.h中定义了7种不同的操作,实际编程时可以参照使用。 semop函数自动执行信号量集合上的操作数组。 int semop(int semid, struct sembuf semoparray[], size_t nops); semoparray是一个指针,它指向一个信号量操作数组。nops规定该数组中操作的数量。 ftok原型如下: key_t ftok( char * fname, int id ) fname就是指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽然为int,但是只有8个比特被使用(0-255)。 当成功执行的时候,一个key_t值将会被返回,否则-1 被返回。 共享内存 共享内存是运行在同一台机器上的进程间通信最快的方式,因为数据不需要在不同的进程间复制。通常由一个进程创建一块共享内存区,其余进程对这块内存区进行读写。首先要用的函数是shmget,它获得一个共享存储标识符。 #include #include #include int shmget(key_t key, int size, int flag); 当共享内存创建后,其余进程可以调用shmat()将其连接到自身的地址空间中。 void *shmat(int shmid, void *addr, int flag); shmid为shmget函数返回的共享存储标识符,addr和flag参数决定了以什么方式来确定连接的地址,函数的返回值即是该进程数据段所连接的实际地

线程实现邮箱通信-实验报告

进程通信实验报告 一、实验名称:进程通信 二、实验目的:掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法。 三、实验原理:邮箱机制类似于日常使用的信箱。对于用户而言使用起来比较方便,用户只需使用send ()向对方邮箱发邮件 receive ()从自己邮箱取邮件, send ()和 receive ()的内部操作用户无需关心。因为邮箱在内存中实现,其空间有大小限制。其实send ()和 receive ()的内部实现主要还是要解决生产者与消费者问题。 四、实验内容:进程通信的邮箱方式由操作系统提供形如send ()和receive ()的系统调用来支持,本实验要求学生首先查找资料了解所选用操作系统平台上用于进程通信的系统调用具体形式,然后使用该系统调用编写程序进行进程间的通信,要求程序运行结果可以直观地体现在界面上。在此基础上查找所选用操作系统平台上支持信号量机制的系统调用具体形式,运用生产者与消费者模型设计实现一个简单的信箱,该信箱需要有创建、发信、收信、撤销等函数,至少能够支持两个进程互相交换信息,比较自己实现的信箱与操作系统本身提供的信箱,分析两者之间存在的异同。 五、背景知识介绍: 1、sembuf 数据结构 struct sembuf { unsigned short int sem_num; //semaphore number short int sem_op; //semaphore operation short int sem_flg; //operation flag }; sem_num :操作信号在信号集中的编号,第一个信号的编号是0。 进程A 进程B 信箱A 信箱B Send() Send() receive() receive()

实验三 软中断通信

实验三软中断通信 实验目的 1、了解什么是信号 2、熟悉LINUX系统中进程之间软中断通信的基本原理 实验内容 1、编写程序:用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按^c键);捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止: Child process1 is killed by parent! Child process2 is killed by parent! 父进程等待两个子进程终止后,输出如下的信息后终止: Parent process is killed! 2、分析利用软中断通信实现进程同步的机理 实验指导 一、信号 1、信号的基本概念 每个信号都对应一个正整数常量(称为signal number,即信号编号。定义在系统头文件中),代表同一用户的诸进程之间传送事先约定的信息的类型,用于通知某进程发生了某异常事件。每个进程在运行时,都要通过信号机制来检查是否有信号到达。若有,便中断正在执行的程序,转向与该信号相对应的处理程序,以完成对该事件的处理;处理结束后再返回到原来的断点继续执行。实质上,信号机制是对中断机制的一种模拟,故在早期的UNIX版本中又把它称为软中断。 信号与中断的相似点: (1)采用了相同的异步通信方式; (2)当检测出有信号或中断请求时,都暂停正在执行的程序而转去执行相应的处理程序;(3)都在处理完毕后返回到原来的断点; (4)对信号或中断都可进行屏蔽。 信号与中断的区别: (1)中断有优先级,而信号没有优先级,所有的信号都是平等的; (2)信号处理程序是在用户态下运行的,而中断处理程序是在核心态下运行; (3)中断响应是及时的,而信号响应通常都有较大的时间延迟。 信号机制具有以下三方面的功能: (1)发送信号。发送信号的程序用系统调用kill( )实现; (2)预置对信号的处理方式。接收信号的程序用signal( )来实现对处理方式的预置;(3)收受信号的进程按事先的规定完成对相应事件的处理。 2、信号的发送 信号的发送,是指由发送进程把信号送到指定进程的信号域的某一位上。如果目标进程正在一个可被中断的优先级上睡眠,核心便将它唤醒,发送进程就此结束。一个进程可能在其信号域中有多个位被置位,代表有多种类型的信号到达,但对于一类信号,进程却只能记住其中的某一个。 进程用kill( )向一个进程或一组进程发送一个信号。

实验6 进程及进程间的通信之共享内存

实验6 进程及进程间的通信 ●实验目的: 1、理解进程的概念 2、掌握进程复制函数fork的用法 3、掌握替换进程映像exec函数族 4、掌握进程间的通信机制,包括:有名管道、无名管道、信 号、共享内存、信号量和消息队列 ●实验要求: 熟练使用该节所介绍fork函数、exec函数族、以及进程间通信的相关函数。 ●实验器材: 软件: 1.安装了Ubunt的vmware虚拟机 硬件:PC机一台 ●实验步骤: 1、用进程相关API 函数编程一个程序,使之产生一个进程 扇:父进程产生一系列子进程,每个子进程打印自己的PID 然后退出。要求父进程最后打印PID。 进程扇process_fan.c参考代码如下:

2、用进程相关API 函数编写一个程序,使之产生一个进程 链:父进程派生一个子进程后,然后打印出自己的PID,然后退出,该子进程继续派生子进程,然后打印PID,然后退出,以此类推。

要求:1) 实现一个父进程要比子进程先打印PID 的版本。(即 打印的PID 一般是递增的) 2 )实现一个子进程要比父进程先打印PID 的版本。(即打印的PID 一般是递减的) 进程链1,process_chain1.c的参考代码如下:

进程链2,process_chain2.c的参考代码如下:

3、编写程序execl.c,实现父进程打印自己的pid号,子进程调用 execl函数,用可执行程序file_creat替换本进程。注意命令行参数。 参考代码如下: /*execl.c*/ #include #include #include

进程软中断通信资料

进程软中断通信 【预备知识】 进程软中断通信涉及的系统调用描述如下。 1.kill() 进程用kill()向一个进程或一组进程发送一个信号。系统调用格式为int kill(pid,sig)。其中,pid是一个或一组进程的标识符,sig是要发送的软中断信号。信号的发送分如下三种情况。 pid>0时,核心将信号发送给进程pid。 pid=0时,核心将信号发送给与发送进程同组的所用进程。 pid=-1时,核心将信号发送给所有用户标识符真正等于发送进程的有效用户标识号的进程。 2.signal(sig,function) 接收信号的程序用signal()来实现对处理方式的预置,允许调用进程控制软中断信号。系统调用格式为signal(sig function),此时需包含头文件signal.h。其中,sig用于指定信号的类型,sig为0则表示没有收到任何信号,其余类型如表所示。 调用函数使用如下头文件: #include 参数定义如下: signal (sig,function) int sig; void(*func) (); function是该进程中的一个函数地址,在核心返回用户态时,它以软中断信号的序号作为参数调用该函数,对除了信号SIGKILL、SIGTRAP和SIGPWR以外的信号,核心自动重新设置软中断信号处理程序的值为SIG_DFL,进程不能捕获SIGKILL信号。 function的解释如下: (1)function=1时,进程对sig类信号不做任何处理便立即返回,亦即屏蔽该类型号。 (2)function=0时,默认值,进程收到sig信号后终止自己。 (3)function为非0、非1类整数时,执行用户设置的软中断处理程序。

进程间通信实验报告

进程间通信实验报告 班级:10网工三班学生姓名:谢昊天学号:1215134046 实验目的和要求: Linux系统的进程通信机构 (IPC) 允许在任意进程间大批量地交换数据。本实验的目的是了解和熟悉Linux支持的消息通讯机制及信息量机制。 实验内容与分析设计: (1)消息的创建,发送和接收。 ①使用系统调用msgget (), msgsnd (), msgrev (), 及msgctl () 编制一长度为1k 的消息的发送和接收程序。 ②观察上面的程序,说明控制消息队列系统调用msgctl () 在此起什么作用? (2)共享存储区的创建、附接和段接。 使用系统调用shmget(),shmat(),sgmdt(),shmctl(),编制一个与上述功能相同的程序。(3)比较上述(1),(2)两种消息通信机制中数据传输的时间。 实验步骤与调试过程: 1.消息的创建,发送和接收: (1)先后通过fork( )两个子进程,SERVER和CLIENT进行通信。 (2)在SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER 。SERVER每接收到一个消息后显示一句“(server)received”。 (3)CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后的一个消息,既是 SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(client)sent”。 (4)父进程在 SERVER和 CLIENT均退出后结束。 2.共享存储区的创建,附接和断接: (1)先后通过fork( )两个子进程,SERVER和CLIENT进行通信。 (2)SERVER端建立一个KEY为75的共享区,并将第一个字节置为-1。作为数据空的标志.等待其他进程发来的消息.当该字节的值发生变化时,表示收到了该消息,进行处理.然后再次把它的值设为-1.如果遇到的值为0,则视为结束信号,取消该队列,并退出SERVER.SERVER 每接收到一次数据后显示”(server)received”. (3)CLIENT端建立一个为75的共享区,当共享取得第一个字节为-1时, Server端空闲,可发送请求. CLIENT 随即填入9到0.期间等待Server端再次空闲.进行完这些操作后, CLIENT退出. CLIENT每发送一次数据后显示”(client)sent”. (4)父进程在SERVER和CLIENT均退出后结束。 实验结果: 1.消息的创建,发送和接收: 由 Client 发送两条消息,然后Server接收一条消息。此后Client Server交替发送和接收消息。最后一次接收两条消息。Client 和Server 分别发送和接收了10条消息。message 的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造成上面现象。在多次send message 后才 receive message.这一点有助于理解消息转送的实现机理。

Linux进程通信实验报告

Linux进程通信实验报告 一、实验目的和要求 1.进一步了解对进程控制的系统调用方法。 2.通过进程通信设计达到了解UNIX或Linux系统中进程通信的基本原理。 二、实验内容和原理 1.实验编程,编写程序实现进程的管道通信(设定程序名为pipe.c)。使 用系统调用pipe()建立一条管道线。而父进程从则从管道中读出来自 于两个子进程的信息,显示在屏幕上。要求父进程先接受子进程P1 发来的消息,然后再接受子进程P2发来的消息。 2.可选实验,编制一段程序,使其实现进程的软中断通信(设定程序名为 softint.c)。使用系统调用fork()创建两个子进程,再用系统调用 signal()让父进程捕捉键盘上来的中断信号(即按Del键),当父进程 接受这两个软中断的其中一个后,父进程用系统调用kill()向两个子 进程分别发送整数值为16和17的软中断信号,子进程获得对应软中 断信号后分别输出相应信息后终止。 三、实验环境 一台安装了Red Hat Linux 9操作系统的计算机。 四、实验操作方法和步骤 进入Linux操作系统,利用vi编辑器将程序源代码输入并保存好,然后 打开终端对程序进行编译运行。 五、实验中遇到的问题及解决 六、实验结果及分析 基本实验 可选实验

七、源代码 Pipe.c #include"stdio.h" #include"unistd.h" main(){ int i,j,fd[2]; char S[100]; pipe(fd); if(i=fork==0){ sprintf(S,"child process 1 is sending a message \n"); write(fd[1],S,50); sleep(3); return; } if(j=fork()==0){ sprintf(S,"child process 2 is sending a message \n"); write(fd[1],S,50); sleep(3); return;

操作系统之进程(生产者_消费者)实验报告

操作系统实验报告 ——生产者和消费者问题 姓名:学号:班级: 一、实验内容 1、模拟操作系统中进程同步和互斥; 2、实现生产者和消费者问题的算法实现; 二、实验目的 1、熟悉临界资源、信号量及PV操作的定义与物理意义; 2、了解进程通信的方法; 3、掌握进程互斥与进程同步的相关知识; 4、掌握用信号量机制解决进程之间的同步与互斥问题; 5、实现生产者-消费者问题,深刻理解进程同步问题; 三、实验题目 在Windows操作系统下用C语言实现经典同步问题:生产者—消费者,具体要求如下: (1)一个大小为10的缓冲区,初始状态为空。 (2)2个生产者,随机等待一段时间,往缓冲区中添加数据,若 缓冲区已满,等待消费者取走数据之后再添加,重复10次。 (3)2个消费者,随机等待一段时间,从缓冲区中读取数据,若 缓冲区为空,等待生产者添加数据之后再读取,重复10次。 四、思想 本实验的主要目的是模拟操作系统中进程同步和互斥。在系统进程并发执行异步推进的过程中,由于资源共享和进程间合作而造成进程间相互制约。进程间的相互制约有两种不同的方式。 (1)间接制约。这是由于多个进程共享同一资源(如CPU、共享

输入/输出设备)而引起的,即共享资源的多个进程因系统协调使用资源而相互制约。 (2)直接制约。只是由于进程合作中各个进程为完成同一任务而造成的,即并发进程各自的执行结果互为对方的执行条件,从而限制各个进程的执行速度。 生产者和消费者是经典的进程同步问题,在这个问题中,生产者不断的向缓冲区中写入数据,而消费者则从缓冲区中读取数据。生产者进程和消费者对缓冲区的操作是互斥,即当前只能有一个进程对这个缓冲区进行操作,生产者进入操作缓冲区之前,先要看缓冲区是否已满,如果缓冲区已满,则它必须等待消费者进程将数据取出才能写入数据,同样的,消费者进程从缓冲区读取数据之前,也要判断缓冲区是否为空,如果为空,则必须等待生产者进程写入数据才能读取数据。 在本实验中,进程之间要进行通信来操作同一缓冲区。一般来说,进程间的通信根据通信内容可以划分为两种:即控制信息的传送与大批量数据传送。有时,也把进程间控制在本实验中,进程之间要进行通信来操作同一缓冲区。一般来说,进程间的通信根据通信内容可以划分为两种:即控制信息的传送与大批量数据传送。有时,也把进程间控制信息的交换称为低级通信,而把进程间大批量数据的交换称为高级通信。 目前,计算机系统中用得比较普遍的高级通信机制可分为3大类:共享存储器系统、消息传递系统及管道通信系统。 ?共享存储器系统 共享存储器系统为了传送大量数据,在存储器中划出一块共享存储区,诸进程可通过对共享存储区进行读数据或写数据以实现通信。

进程同步实验报告

实验三进程的同步 一、实验目的 1、了解进程同步和互斥的概念及实现方法; 2、更深一步的了解fork()的系统调用方式。 二、实验内容 1、预习操作系统进程同步的概念及实现方法。 2、编写一段源程序,用系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。程序的输出是什么?分析原因。 3、阅读模拟火车站售票系统和实现进程的管道通信源代码,查阅有关进程创建、进程互斥、进程同步的系统功能调用或API,简要解释例程中用到的系统功能或API的用法,并编辑、编译、运行程序,记录程序的运行结果,尝试给出合理的解释。 4、(选做)修改问题2的代码,使得父子按顺序显示字符“a”;“b”、“c”编辑、编译、运行。记录程序运行结果。 三、设计思想 1、程序框架 (1)创建两个子进程:(2)售票系统:

(3)管道通信: 先创建子进程,然后对内容加锁,将输出语句存入缓存,并让子进程自己进入睡眠,等待别的进程将其唤醒,最后解锁;第二个子进程也执行这样的过程。父进程等待子进程后读内容并输出。 (4)修改程序(1):在子进程的输出语句前加上sleep()语句,即等待父进程执行完以后再输出。 2、用到的文件系统调用函数 (1)创建两个子进程:fork() (2)售票系统:DWORD WINAPI Fun1Proc(LPVOID lpPartameter); CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); CloseHandle(hThread1); (HANDLE)CreateMutex(NULL,FALSE,NULL); Sleep(4000)(sleep调用进程进入睡眠状态(封锁), 直到被唤醒); WaitForSingleObject(hMutex,INFINITE); ReleaseMutex(hMutex); (3)管道通信:pipe(fd),fd: int fd[2],其中: fd[0] 、fd[1]文件描述符(读、写); lockf( fd,function,byte)(fd: 文件描述符;function: 1: 锁定 0:解锁;byte: 锁定的字节数,0: 从当前位置到文件尾); write(fd,buf,byte)、read(fd,buf,byte) (fd: 文件描述符;buf : 信息传送的源(目标)地址;byte: 传送的字节数); sleep(5); exit(0); read(fd[0],s,50) (4)修改程序(1):fork(); sleep(); 四、调试过程 1、测试数据设计 (1)创建两个子进程:

操作系统进程创建及通信实验报告

武汉工程大学计算机科学与工程学院 《操作系统》实验报告[Ⅰ]

一、实验目的 创建进程,实现进程消息通信和共享内存通信,了解进程的创建、退出和获取进程信。了解什么是映像文件、管道通信及其作用,掌握通过内存映像文件和管道技术实现进程通信。 二、实验内容 本例用三种方法实现进程通信,仅用于示例目的,没有进行功能优化。 1、创建进程A和B后,在进程A中输入一些字符,点“利用 SendMessage发送消息”按钮可将消息发到进程B。 2、在进程A中输入一些字符,点“写数据到内存映像文件”按钮, 然后在进程B中点“从内存映像文件读数据”按钮可收到消息。其中在点“写数据到内存映像文件”时,要求创建映像文件,B进程在印象文件中读取数据。 3、先在进程B中点“创建管道并接收数据”按钮,然后在进程A 中输入一些字符,点“写数据到管道文件”按钮可将消息发到进程B。管道是连接读/写进程使他们进行通信的一个共享文件,目的是更好地实现进程间的通信。 三、实验思想 这次试验最主要的内容和核心思想就是学会创建进程并实现进程间的简单通信、创建映像文件和创建管道文件来通信,后两者是实现进程通信的高级通信机制中的两种。. 创建一个程序A和程序B,其中程序A和B各有一个主窗体,A主窗体上要求可以实现创建进程B(即调用函数B)、结束进程B、关闭进程A、向进程B发送数据、创建映像文件、创建管道文件等功能,进程B要求有从映像文件读取数据、创建管道并接收数据、结束进程B功能。最终让A、B进程相互通信。

四、设计分析: 首先设得设计A、B两个程序的操作界面,然后编写各个功能模块。对于A 程序窗体,在“利用SendMessage发送消息”按钮的消息响应函数中,主要是利用Windows API函数CWnd::FindWindow来找到接收消息的窗体,即进程B,找到进程B后,利用这个函数返回的窗体指针的SendMessage函数来发送消息。在“写数据到内存印象文件”按钮的消息响应函数中,主要是利用函数CreateFileMapping来创建一个印象文件,这个函数返回的是这个印象文件的句柄,然后将这个句柄和要发送的消息字符串传递到函数sprintf中,就可以所要发送的消息写入印象文件,在B程序窗体中有个“从内存印象文件读数据”按钮,在这个按钮的消息响应函数中读取父进程所创建的印象文件中的数据就可以实现通信了。在B程序窗体按钮“写数据到管道文件”的消息响应函数中,不能直接将要发送的消息发送到管道文件,因为管道必须先由子进程通过函数CreateNamedPipe创建,只有待子进程创建好管道后父进程才能根据管道创建管道文件,将消息写入管道文件并及时发送给子进程。而且这个管道只能使用一次,即每次发送完消息后那个管道不能在使用了,必须再由子进程创建一个管道,A 进程才能再次创建管道文件并向其中写入消息。这个程序也不一定要MFC实现,还可以用其他的技术和语言实现,比如说Java、VB等,外表构架可以不一样,但核心技术都是一样的,只是不同的调用形式和调用方法,比如说在VB中,实现进程间的一般通信就是使用动态数据交换DDE,实现起来就比较简单,但是要创建映像文件和管道文件就比较繁琐,可以根据不同的需求采用不同的语言。 五、程序部分源代码: 1.“利用SendMessage发送消息”按钮中的主要代码 //找到接收消息的窗口(窗口名为Receiver) CString str="进程B"; CWnd *pWnd=CWnd::FindWindow(NULL,str); if(pWnd) { COPYDATASTRUCT buf; char * s=new char[m_Msg1.GetLength()]; //m_Msg1为CString类型的变量 s=m_Msg1.GetBuffer(0);

实验一 进程管理

实验一进程管理 1. 实验目的 ⑴加深对进程概念的理解,明确进程和程序的区别; ⑵进一步认识并发执行的实质; ⑶分析进程争用资源的现象,学习解决进程互斥的方法; ⑷了解Linux系统中进程通信的基本原理。 2. 实验准备 ⑴阅读Linux的sched.h源码文件,加深对进程管理的理解。 ⑵阅读Linux的fork.h源码文件,分析进程的创建过程。 3. 实验内容 ⑴进程的创建 编写一段程序,使用系统调用fork ( )创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程显示字符“b”和字符“c”。试观察记录屏幕上的显示结果,并分析原因。 ⑵进程的控制 修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。 如果在程序中使用系统调用lockf ( )来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。 ⑶软中断通信 编制一段程序实现进程的软中断通信。要求:使用系统调用fork ( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上发来的中断信号(既按Del键);当捕捉到中断信号后,父进程系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:Child process 1 is killed by parent! Child process 2 is killed by parent! 父进程等待两个子进程终止后,输出如下的信息后终止: Parent process is killed! 在上面的程序中增加语句signal (SIGINT, SIG_IGN) 和signal (SIGQUIT, SIG_IGN),观察执行结果,并分析原因。 4. 实验指导

进程控制与进程间通信操作系统实验报告

工程大学实验报告 专业班级:姓名:学号: 课程名称:操作系统 实验成绩:指导教师:蔡敦波 实验名称:进程控制与进程间通信 一、实验目的: 1、掌握进程的概念,明确进程和程序的区别。 2、认识和了解并发执行的实质。 3、了解什么是信号。 4、熟悉LINUX系统中进程之间软中断通信的基本原理。 二、实验内容: 1、进程的创建(必做题) 编写一段程序,使用系统调用fork( )创建两个子进程,在系统中有一个父进程和两个子进程活动。让每个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。 <参考程序>

运行的结果是bca. 首先创建进程p1,向子进程返回0,输出b.又创建进程p2,向子进程返回0,输出c,同时向父进程返回子进程的pid,输出a 2、修改已编写的程序,将每个进程的输出由单个字符改为一句话,再观察程序执行时屏幕上出现的现象,并分析其原因。(必做题) <参考程序> # include int main() { int p1, p2, i; while((p1=fork())= = -1); if(p1= =0) for(i=0;i<500;i++) printf(“child%d\n”,i); else { while((p2=fork())= =-1); If(p2= =0) for(i=0;i<500;i++) printf(“son%d\n”,i); else for(i=0;i<500;i++) printf(“daughter%d\n”,i); } }

运行的结果是如上图所示. 首先创建进程p1,向子进程返回0,并for语句循环输出child +i字符串.又创建进程p2,向子进程返回0,输出字符串son+i,同时向父进程返回子进程的pid,输出字符串duaghter +i ,各打印5次。

实验5 进程间通信实验

实验五进程间通信实验 一、实验目的 1、了解什么是信号。 2、熟悉LINUX系统中进程之间软中断通信的基本原理。 3、了解什么是管道 4、熟悉UNIX/LINUX支持的管道通信方式 二、实验内容 1、编写一段程序,使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:Child process 1 is killed by parent! Child process 2 is killed by parent! 父进程等待两个子进程终止后,输出以下信息后终止: Parent process is killed! <参考程序> #include #include #include #include #include int wait_mark; void waiting(),stop(); void main() {int p1, p2; signal(SIGINT,stop); while((p1=fork())==-1); if(p1>0) /*在父进程中*/ { while((p2=fork())==-1); If(p2>0) /*在父进程中*/ { wait_mark=1; waiting(0); kill(p1,10); kill(p2,12); wait( ); wait( ); printf("parent process is killed!\n"); exit(0); } else /*在子进程2中*/ { wait_mark=1; signal(12,stop); waiting();

实验报告三进程管理及进程通信

实验三进程管理及进程通信 实验环境: Linux操作系统 实验目的: (1)利用Linux提供的系统调用设计程序,加深对进程概念的理解。 (2)体会系统进程调度的方法和效果。 (3)了解进程之间的通信方式以及各种通信方式的使用。 实验方法: 用vi 编写c 程序(假定程序文件名为prog1.c)编 译程序 $ gcc -o prog1.o prog1.c 或 $ cc -o prog1.o prog1.c 运行 $./prog1.o 实验内容及步骤: 实验1 编写程序。显示进程的有关标识(进程标识、组标识、用户标识等)。经过5 秒钟后,执行另一个程序,最后按用户指示(如:Y/N)结束操作。 编程截图:

运行结果: 实验2 参考例程1,编写程序。实现父进程创建一个子进程。体会子进程与父进程分 别获得不同返回值,进而执行不同的程序段的方法。 例程1:利用fork()创建子进程 /* 用fork()系统调用创建子进程的例子*/ main() { int i; if (fork()) /*父进程执行的程序段*/ i=wait(); /* 等待子进程结束*/{ printf("It is parent process.\n"); printf("The child process,ID number %d, is finished.\n",i); } else{

Printf(“It is child process.\n”); Sleep(10); Exit(); } } 运行结果: 思考: 子进程是如何产生的?又是如何结束的?子进程被创建后它的运行环境是怎样建立的? 答:是由父进程用fock()函数创建形成的,通过exit()函数自我结束,子进程被创建后核心 将其分配一个进程表项和进程标识符,检查同时运行的进程数目,并且拷贝进程表项的数据,由子进程继承父进程所有文件。 实验3 参考例程2,编写程序。父进程通过循环语句创建若干子进程。探讨进程的家族树 以及子进程继承父进程的资源的关系。 例程2:循环调用fork()创建多个子进程。 /*建立进程树*/ #include main() { int i; printf(“My pid is %d, my father’s pid is %d\n”,getpid() ,getppid()); for(i=0; i<3; i++) if(fork()==0) printf(“%d pid=%d ppid=%d\n”, i,getpid(),getppid()); else { j=wait(0); Printf(“%d:The chile %d is finished.\n”,getpid(),j);

extremeDB使用例子

来一份eXtremeDB使用笔记. 1、准备工作:下载eXtremeDB安装包(https://www.doczj.com/doc/b417072961.html,/)然后将安装或解压至磁盘。此时可以看到其目录下有host、include、platform和target等目录。 2、用你喜欢的文本编辑器构建一数据库结构,文本内容如下:(举例说明,保存文件名为test.mco) #define int1 signed<1> #define int2 signed<2> #define int4 signed<4> #define int8 signed<8> #define uint8 unsigned<8> #define uint4 unsigned<4> #define uint2 unsigned<2> #define uint1 unsigned<1> // db over shm memory test declare database shmdb; //数据名字 compact class MyClass //表名字 { unsigned<4> id; string str1; char<20> str2; unique tree pkey; //索引 }; 3、用host in目录里的mcocomp.exe程序在DOS命令行模式下将test.mco编译生成,用法如: 》mcocomp test.mco 编译成功后将会生成shmdb.h和shmdb.c文件。当然了,可以根据需要生成所需的文件,具体请见mcocomp命令的参数(mcocomp -help)。至此,生成的文件里就含有数据库操作所需要API函数了。 4、新建一控制台程序工程为shmdb,在链接库里加上mcolib_shm.lib(此处为共享内存LIB库),此处需要注意LIB的路径,最简单的办法就是将eXtremeDB的库文件拷贝至工程目录下包含其就可以了。 5、将编译生成的shmdb.h和shmdb.c添加至此工程中。然后新建一C文件shmdemo.c(当然了,也可以是.cpp文件),下面将分别讲解shmdemo.c文件代码。先看此文件的全部代码: /*标准库*/

北邮-大三-操作系统-进程管理实验报告

实验一进程管理 1.实验目的: (1)加深对进程概念的理解,明确进程和程序的区别; (2)进一步认识并发执行的实质; (3)分析进程争用资源的现象,学习解决进程互斥的方法; (4)了解Linux系统中进程通信的基本原理。 2.实验预备内容 (1)阅读Linux的源码文件,加深对进程管理概念的理解; (2)阅读Linux的fork()源码文件,分析进程的创建过程。 3.实验内容 (1)进程的创建: 编写一段程序,使用系统调用fork() 创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”,子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。 源代码如下: #include #include<> #include<> #include <> #include <> int main(int argc,char* argv[]) { pid_t pid1,pid2; pid1 = fork(); if(pid1<0){ fprintf(stderr,"childprocess1 failed"); exit(-1); } else if(pid1 == 0){

printf("b\n"); } else{ pid2 = fork(); if(pid2<0){ fprintf(stderr,"childprocess1 failed"); exit(-1); } else if(pid2 == 0){ printf("c\n"); } else{ printf("a\n"); sleep(2); exit(0); } } return 0; } 结果如下: 分析原因: pid=fork(); 操作系统创建一个新的进程(子进程),并且在进程表中相应为它建立一个新的表项。新进程和原有进程的可执行程序是同一个程序;上下文和数据,绝大部分就是原进程(父进程)的拷贝,但它们是两个相互独立的进程!

共享内存的原理

共享内存 不同进程共享内存示意图 共享内存指在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存(shared memory)是 Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。 目录 共享内存的创建 共享内存是存在于内核级别的一种资源,在shell中可以使用ipcs命令来查看当前系统IPC中的状态,在文件系统/proc目录下有对其描述的相应文件。函数shmget可以创建或打开一块共享内存区。函数原型如下:#include int shmget( key_t key, size_t size, int flag );

函数中参数key用来变换成一个标识符,而且每一个IPC对象与一个key相对应。当新建一个共享内存段时,size参数为要请求的内存长度(以字节为单位)。 注意:内核是以页为单位分配内存,当size参数的值不是系统内存页长的整数倍时,系统会分配给进程最小的可以满足size长的页数,但是最后一页的剩余部分内存是不可用的。 当打开一个内存段时,参数size的值为0。参数flag中的相应权限位初始化ipc_perm结构体中的mode域。同时参数flag是函数行为参数,它指定一些当函数遇到阻塞或其他情况时应做出的反应。shmid_ds结构初始化如表14-4所示。 初始化

软中断实验报告

篇一:linux软中断通信实验报告 实验2 linux软中断通信 1.实验目的 通过本实验,掌握软中断的基本原理;掌握中断信号的使用、进程的创建以及系统计时器的使用。 2.实验内容(上交的实验2统一取名为:test2) 由父进程创建两个子进程,通过终端输入crtl+\组合键向父进程发送sigquit软中断信号或由系统时钟产生sigalrm软中断信号发送给父进程;父进程接受到这两个软中断的其中某一个后,向其两个子进程分别发送整数值为16和17软中断信号,子进程获得对应软中断信号后,终止运行;父进程调用wait()函数等待两个子进程终止,然后自我终止。 3. 设计思想及算法流程 4. 源程序 #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #define sec 5 void waiting(); void stop(); int wait_mark; int main() { int p1, p2; /*定义两个进程号变量*/while ((p1 = fork()) == -1); /*循环创建进程至成功为止*/if (p1 > 0) { while ((p2 = fork()) == -1); /*循环创建进程至成功为止*/ if (p2 > 0) { wait_mark = 1; alarm(sec); signal(sigquit, stop); signal(sigalrm, stop); waiting(); kill(p1, 16); kill(p2, 17); wait(0); wait(0); printf(parent process is killed!\n); exit(0); } else { signal(sigquit, sig_ign); signal(sigalrm, sig_ign); wait_mark = 1; signal(17, stop); /*接收到软中断信号17,转stop*/ waiting();/*在wait置0前,不可往下执行*/lockf(1, 1, 0); /*加锁*/ printf(child process 2 is killed by parent!\n);

操作系统上实验报告3

操作系统实验三报告 实验题目: 进程管理及进程通信 实验环境: 虚拟机Linux操作系统 实验目的: 1.利用Linux提供的系统调用设计程序,加深对进程概念的理解。 2.体会系统进程调度的方法和效果。 3.了解进程之间的通信方式以及各种通信方式的使用。

实验内容: 例程1: 利用fork()创建子进程 #include<> #include<> #include<> main() { int i; if (fork()) i=wait(0); /*父进程执行的程序段*/ /* 等待子进程结束*/ printf("It is parent process.\n"); printf("The child process,ID number %d, is finished.\n",i); } else{ printf("It is child process.\n"); sleep(10); /*子进程执行的程序段*/ exit(1); /*向父进程发出结束信号*/ } } 运行结果: 思考:子进程是如何产生的又是如何结束的子进程被创建后它的运行环境是怎样建立的

答:子进程是通过函数fork()创建的,通过exit()函数自我结束的,子进程被创建后核心将为其分配一个进程表项和进程标识符,检查同时运行的进程数目,并且拷贝进程表项的数据,由子进程继承父进程的所有文件。 例程2: 循环调用fork()创建多个子进程 #include<> #include<> #include<> main() { int i,j; printf(“My pid is %d, my father’s p id is %d\n”,getpid() ,getppid()); for(i=0; i<3; i++) if(fork()==0) printf(“%d pid=%d ppid=%d\n”, i,getpid(),getppid()); else { j=wait(0); Printf(“ %d:The chile %d is finished.\n” ,getpid(),j); } } 运行结果:

相关主题
文本预览
相关文档 最新文档