2024年4月29日发(作者:)

广东海洋大学操作系统.实验

(1)

-CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIAN

班级:计科1141 学号:1110 姓名:邓超荣

实验一 进程同步与互斥

实验目的 了解多进程并发执行时因控制不当而导致的运行结果不确定的竞争条

件现象、以及消除竞争条件所采取的措施。

实验内容

有一个数据文件,名字是data,其中存放了一个十进制正整数。现有一个程序,

该程序读出文件data中的数据、将其加一、再将结果更新到data之中,上述

动作重复进行一百万次。如下给出完成上述功能的源程序:

01 #include <>

02 #include <>

03 #include <>

04 #include

05 #include <>

06 #include <>

07 #include <>

08 int main()

09 {

10 int num,

fd,i;

不改变程序代码的情况下,怎样把上述程序作为多个进程来并发执行请观察并

发执行情况下的运行结果,分析运行结果错误的具体原因。

答:要实现多进程并发执行,可多个窗口对同一程序进行运行。

由于data文件初始值为1234,所以两个进程在并发执行的情况下,正确结果

应该为2001234,可是最后结果却为1509625。显然与正确结果不符。此主要原

因在于,在两个进程同时执行的时候,可能会在同一时间对num进行操作,导

致重读,如原本进程1对2加1后为3,进程而对3加1后为4.而现实中可能

产生的情况是进程1和进程2同时对2进行加1操作,所以得到最终结果是3

而不是4;另一种情况是,进程1已进行了加1操作但在保存到文件之前,进

程2执行到读取文件数据,因此,进程2读取的还是原本数据,进行加1操作

后仍然是进程1执行操作后的数据。所以当多进程并发执行时,最后得出的结

果与预想中的结果不同。

3.请修改上述代码,采用上锁方式,以保证并发执行时运行结果的正确性,并

分析得到了正确结果的原因。

修改后,代码如下:

#include <>

#include <>

#include <>

#include

#include <>

#include <>

#include <>

int main()

{

struct flock fl;//定义结构体flock,设置锁

int num, fd,i;

char buff[100];

fd = open("data", O_RDWR);

if(fd<=0){

printf("open errorn");

return 1;

}

= SEEK_SET;//设置文件读写位置

= 1;//开始位置为1

= 1;//长度为1

= getpid();//获取进程

for(i=1;i<=1000000;i++){

= F_WRLCK;//对文件加锁

fcntl(fd, F_SETLKW, &fl);//对文件逐个扫描

lseek(fd, 0, SEEK_SET);

int len = read(fd, buff, 100);

buff[len]='0';

num = atoi(buff);

sprintf(buff, "%dn", num + 1);

lseek(fd, 0, SEEK_SET);

write(fd, buff,strlen(buff));

= F_UNLCK;//解锁文件

fcntl(fd, F_SETLKW, &fl);

}

close(fd);

return 0;

}

该程序分析结果如下:当进程1对文件进行操作时,对文件进行加锁,防止其

他进程对文件同时操作,也就是,其他进程阻塞。当进程1完成操作对文件解

锁后,进程2被唤醒,进而对文件进行操作,在操作前,同样对文件进行加

锁。如此类推,对个进程交替执行,保证了结果的正确性。

实验心得:

写出你对单次执行和并发进程的感受,操作系统对并发进程控制的重要性。

在数据量比较少的情况下,单次执行的速度比并发执行的速度占有一定的

优势。但在数据量的达到百万上亿的时候,单次执行的速度明显不尽人意。而

并发执行能多个进程同时对一个程序进行操作,就如,工厂里生产汽车零件,

一个人一天的产量必定少于多个人的共同完成生产零件一个的产量。当然,物

极必反,并不是说进程越多越好,当进程增多,就容易出现进程空闲的情况,

导致性能的下降。操作系统每天都要处理庞大的数据,若使用单次执行方式,

不单会导致系统运行速度慢,还会让使用者陷于崩溃的等待中,所以,操作系

统对并发执行的应用与控制显得更重要。