Linux创建进程及同步

主要任务:

1.编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程输出不同的内容。试观察记录屏幕上的显示结果,并分析原因。

2.修改上述程序,每一个进程循环显示一句话。子进程显示'daughter  …'及'son  ……',父进程显示 'parent  ……',观察结果,分析原因。

3.再调用exec( )用新的程序替换该子进程的内容 ,并利用wait( )来控制进程执行顺序。调用Exit()使子进程结束。

4.利用linux的信号量机制实现生产者-消费者问题。(基于进程)


1.新建一个test.c文件,将需要的程序写入文件中

vim test.c

.Linux创建进程及同步

gcc -o test test.c

./test

Linux创建进程及同步

分析原因:从进程并发执行来看,各种情况都有可能。上面的三个进程没有同步措施,所以父进程与子进程的输出内容会叠加在一起。输出次序带有随机性。

2.新建一个test.c文件,将需要的程序写入文件中

Linux创建进程及同步

编译:gcc -o test test.c

执行:./test

Linux创建进程及同步

分析原因:由于函数printf()在输出字符串时不会被中断,因此,字符串内部字符顺序输出不变。但由于进程并发执行的调度顺序和父子进程抢占处理机,输出字符串的顺序和先后随着执行的不同而发生变化

3.系统调用exec()系列,用于新程序的执行。fork()只是将父进程的用户级上下文拷贝到新进程中,而exec()系列可以将一个可执行的二进制文件覆盖在新进程的用户级上下文的存储空间上,已更改新进程的用户级上下文。exec()系列中的系统调用都完成相同的功能,把一个新程序装入内存,来改变调用进程的执行代码,从而形成新进程。

exec()没有建立一个与调用进程并发的子进程,而是用新进程取代了原来的进程。exec()系列系统在系统库unistd.h中,共有execl、execlp、execle、execv、execvp五个,基本功能相同,只是以不同的方式来给出参数。

添加代码进入文件

Linux创建进程及同步

./aaa

Linux创建进程及同步



4.可以这样描述这个问题,有一个或者多个生产者产生某种类型的数据,并放置在固定大小的缓冲区中,一个消费者从缓冲区中取数据,每次取一项,系统必须保证对缓冲区的重复操作,任何时候,只有一个生产者或者消费者可以访问缓冲区;同时,消费者只能在缓冲区不为空的时候从缓冲区中读数据,生产者只能在缓冲区不为满的时候向缓冲区写入数据。

上面的问题总结起来有两点:

第一是缓冲区的互斥访问问题,任意时刻最多只能有一个线程访问缓冲区,linux下可以使用互斥量pthread_mutex_t对访问缓冲区的临界区代码进行保护。

第二是生产者和消费者对缓冲区访问的同步问题,生产者在缓冲区满时不能向缓冲区中写入数据,同时消费者在缓冲区空时不能读取数据,这里采用两个信号量room_sem和product_sem 来对缓冲区进行同步。

实现代码如下:

Linux创建进程及同步

Linux创建进程及同步

Linux创建进程及同步

Linux创建进程及同步

运行结果:

Linux创建进程及同步

通过这次的实习任务,加深了自己对Linux创建进程的理解,能够自己亲自动手完成进程的同步过程。虽然在过程中也遇到了各种各样的错误,但通过网上查阅资料、与同学们一起探索讨论,最终解决了这些错误,完成了任务。希望自己在以后的学习中也能够勤动手,多练习,让自己的动手编程能力和逻辑思维能力得到提升。