2022年操作系统实验 8.pdf
《2022年操作系统实验 8.pdf》由会员分享,可在线阅读,更多相关《2022年操作系统实验 8.pdf(12页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、实验二进入 VI 编辑器格式: vi 文件名例 :vi sy.c Vi 编辑器三种工作方式:1编辑方式:进入VI 处于编辑方式2文本输入方式:在编辑方式下输入a ,进入追加方式,输入i,进入插入方式3 命令方式:在输入方式下,按Esc 键,由文本输入转向编辑方式,输入冒号:进入命令方式4退出 vi : wq 写文件退出:w wenjianming 写文件: q! 不写退出:wq! 写退出编译 c 文件Gcc -o wenjianming.out wenjianming.c 运行文件:./wenjianming.out 1 实验内容和目的用 vi 编辑器编辑下列文件,使用gcc 编译器和gdb
2、调试器,对下列程序编译运行,分析运行结果。要求至少完成3 个程序。2程序示例(1) /* 父子进程之间的同步之例*/ #include main( ) int pid1; if(pid1=fork() /*create child1 */ if (fork() /*create the child2*/ printf (“ parent n” );printf(“ parent is waiting the child1 terminate.n); wait(0); printf(“ parent is waiting the child2 terminate.n” );wait(0); pr
3、intf(“ parent terminate.n” );exit(0); else /* child2*/ printf(“ child2 s context.n” );名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 12 页 - - - - - - - - - sleep(5); printf(“ child2 terminate.n” );exit(0); else if(pid1=0)/* child1 */ printf(“ child1 s context.n
4、” );sleep(10); printf(“ child1 terminate.n” );exit(0); 分析:上述程序是父进程首先创建一个子进程,若成功,再创建另一个子进程,之后三个进程并发执行。 究竟谁先执行,是随机的,可根据执行结果判断。试分析该程序的所有运行结果。注释:fork( ) 调用正确完成时,给父进程返回地是被创建子进程的标识,给子进程返回的是 0;创建失败时,返回给父进程的时1;exit(0) 进程终止自己wait(0) 父进程同步等待子进程结束,即无子进程结束,父进程等待。(2)管道通信机制通过使用管道实现两个和多个进程之间的通信。所谓管道,就是将一个进程的标准输出与另
5、一个进程的标准输入联系在一起,进行通信的一种方法。同组进程之间可用无名管道进行通信,不同组进程可通过有名管道通信。使用无名管道进行父子进程之间的通信 include #include #include int pipe( int filedes2); char parent=” a message to pipe communication.n” ;main() int pid,chan12; char buf100; pipe(chan1); pid=fork(); if(pid0) close(chan10); /* 父进程关闭读通道*/ printf(“ parent process s
6、ends a message to child.n” );write(chan11,parent,sizeof(parent); close(chan11); printf(“ parent process waits the child to terminate.n” );名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 12 页 - - - - - - - - - wait(0); printf(“ parent process terminates.n” ); els
7、e close(chan11);/* 子进程关闭写通道*/ read(chan10,buf,100); printf(“ the message read by child process form parent is %s.n” ,buf);close (chan10); printf(“ child process terminatesn” ); 观察运行结果。注释 :pipe( int filedes2) :创建一个无名管道,filedes0 为读通道, filedes1 为写通道。(3)Linux 中的多线程编程threads.c #include #include #include
8、#include #define MAX 10 pthread_t thread2; pthread_mutex_t mut; int number=0, i; void *thread1() printf (thread1 : Im thread 1n); for (i = 0; i MAX; i+) printf(thread1 : number = %dn,number); pthread_mutex_lock(&mut); number+; pthread_mutex_unlock(&mut); sleep(2); printf(thread1 :主函数在等我完成任务吗?n); pth
9、read_exit(NULL); void *thread2() printf(thread2 : Im thread 2n); for (i = 0; i MAX; i+) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 12 页 - - - - - - - - - printf(thread2 : number = %dn,number); pthread_mutex_lock(&mut); number+; pthread_mutex_unlock(&mut); s
10、leep(3); printf(thread2 :主函数在等我完成任务吗?n); pthread_exit(NULL); void thread_create(void) int temp; memset(&thread, 0, sizeof(thread); /comment1 /*创建线程 */ if(temp = pthread_create(&thread0, NULL, thread1, NULL) != 0) /comment2 printf(线程 1 创建失败 !n); else printf(线程 1 被创建 n); if(temp = pthread_create(&thre
11、ad1, NULL, thread2, NULL) != 0) /comment3 printf(线程 2 创建失败 ); else printf(线程 2 被创建 n); void thread_wait(void) /*等待线程结束*/ if(thread0 !=0) /comment4 pthread_join(thread0,NULL); printf(线程 1 已经结束 n); if(thread1 !=0) /comment5 pthread_join(thread1,NULL); printf(线程 2 已经结束 n); int main() 名师资料总结 - - -精品资料欢迎
12、下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 12 页 - - - - - - - - - /*用默认属性初始化互斥锁*/ pthread_mutex_init(&mut,NULL); printf(我是主函数哦,我正在创建线程,呵呵n); thread_create(); printf(我是主函数哦,我正在等待线程完成任务阿,呵呵n); thread_wait(); return 0; 3 注意: Gcc lpthread o thread.out thread.c线程相关操作1) pthread_t
13、pthread_t 在头文件 /usr/include/bits/pthreadtypes.h 中定义:typedef unsigned long int pthread_t; 它是一个线程的标识符。2)pthread_create 函数 pthread_create 用来创建一个线程,它的原型为:extern int pthread_create _P (pthread_t *_thread, _const pthread_attr_t *_attr, void *(*_start_routine) (void *), void *_arg); 第一个参数为指向线程标识符的指针,第二个参数用
14、来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。这里,我们的函数thread不需要参数,所以最后一个参数设为空指针。第二个参数我们也设为空指针,这样将生成默认属性的线程。 对线程属性的设定和修改我们将在下一节阐述。当创建线程成功时,函数返回 0, 若不为 0则说明创建线程失败, 常见的错误返回代码为EAGAIN 和 EINVAL 。前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法。创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。3)pthread_join pthread_ex
15、it 函数 pthread_join 用来等待一个线程的结束。函数原型为:extern int pthread_join _P (pthread_t _th, void *_thread_return); 第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit 来实现。它的函数原型为:extern void
16、 pthread_exit _P (void *_retval) _attribute_ (_noreturn_); 唯一的参数是函数的返回代码,只要pthread_join中的第二个参数thread_return 不是NULL ,这个值将被传递给thread_return。最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join 的线程则返回错误代码 ESRCH。在这一节里, 我们编写了一个最简单的线程,并掌握了最常用的三个函数pthread_create,名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - -
17、 - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 12 页 - - - - - - - - - pthread_join 和 pthread_exit。下面,我们来了解线程的一些常用属性以及如何设置这些属性。互斥锁相关互斥锁用来保证一段时间内只有一个线程在执行一段代码。1) pthread_mutex_init 函数 pthread_mutex_init 用来生成一个互斥锁。NULL 参数表明使用默认属性。如果需 要 声 明 特 定 属 性 的 互 斥 锁 , 须 调 用 函 数pthread_mutexattr_init 。 函 数pthread_m
18、utexattr_setpshared 和函数pthread_mutexattr_settype 用来设置互斥锁属性。前一个函数设置属性pshared,它有两个取值,PTHREAD_PROCESS_PRIVATE和PTHREAD_PROCESS_SHARED 。前者用来不同进程中的线程同步,后者用于同步本进程的不同线程。在上面的例子中,我们使用的是默认属性PTHREAD_PROCESS_ PRIVATE 。后者用来设置互斥锁类型,可选的类型有PTHREAD_MUTEX_NORMAL、PTHREAD_MUTEX_ERRORCHECK、 PTHREAD_MUTEX_RECURSIVE和 PTHRE
19、AD _MUTEX_DEFAULT。它们分别定义了不同的上锁、解锁机制,一般情况下,选用最后一个默认属性。2) pthread_mutex_lock pthread_mutex_unlock pthread_delay_np pthread_mutex_lock 声明开始用互斥锁上锁,此后的代码直至调用pthread_mutex_unlock为 止 , 均 被 上 锁 , 即 同 一 时 间 只 能 被 一 个 线 程 调 用 执 行 。 当 一 个 线 程 执 行 到pthread_mutex_lock 处时,如果该锁此时被另一个线程使用,那此线程被阻塞,即程序将等待到另一个线程释放此互斥锁
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年操作系统实验 2022 操作系统 实验
限制150内