好文档 - 专业文书写作范文服务资料分享网站

操作系统实验(实验2-5)

天下 分享 时间: 加入收藏 我要投稿 点赞

实验二

进入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调试器,对下列程序编译运行,分析运行结果。要求至少完成3个程序。 2.程序示例

(1) /* 父子进程之间的同步之例 */ #include main( ) {

int pid1;

if(pid1=fork()) /*create child1 */

{ if (fork()) /*create the child2*/

{printf (“parent’s context.\\n”);

printf(“parent is waiting the child1 terminate.\\n); wait(0);

printf(“parent is waiting the child2 terminate.\\n”); wait(0);

printf(“parent terminate.\\n”); exit(0); } else

/* child2*/

printf(“child2’s context.\\n”);

sleep(5);

printf(“ child2 terminate.\\n”); exit(0); }

else { if(pid1==0)/* child1 */ { printf(“child1’s context.\\n”); sleep(10);

printf(“child1 terminate.\\n”); exit(0); } } }

分析: 上述程序是父进程首先创建一个子进程,若成功,再创建另一个子进程,之后三个进程并发执行。究竟谁先执行,是随机的,可根据执行结果判断。试分析该程序的所有运行结果。

注释: fork( ) 调用正确完成时,给父进程返回地是被创建子进程的标识,给子进程返回的是0;创建失败时,返回给父进程的时-1; exit(0) 进程终止自己

wait(0) 父进程同步等待子进程结束,即无子进程结束,父进程等待。 (2)管道通信机制

通过使用管道实现两个和多个进程之间的通信。所谓管道,就是将一个进程的标准输出与另一个进程的标准输入联系在一起,进行通信的一种方法。同组进程之间可用无名管道进行通信,不同组进程可通过有名管道通信。

使用无名管道进行父子进程之间的通信 #include #include #include int pipe( int filedes[2]);

char parent[]=”a message to pipe’ communication.\\n”; main()

{ int pid,chan1[2]; char buf[100]; pipe(chan1); pid=fork(); if(pid<0)

{ printf(“to create child error\\n”); exit(1); }

if(pid>0)

{ close(chan1[0]); /*父进程关闭读通道*/

printf(“parent process sends a message to child.\\n”); write(chan1[1],parent,sizeof(parent)); close(chan1[1]);

printf(“parent process waits the child to terminate.\\n”);

wait(0);

printf(“parent process terminates.\\n”); } else{

close(chan1[1]);/*子进程关闭写通道*/ read(chan1[0],buf,100);

printf(“the message read by child process form parent is %s.\\n”,buf); close (chan1[0]);

printf(“child process terminates\\n”); } }

观察运行结果。

注释:pipe( int filedes[2]):创建一个无名管道,filedes[0]为读通道,filedes[1]为写通道。 (3)Linux中的多线程编程threads.c #include #include #include #include #define MAX 10

pthread_t thread[2]; pthread_mutex_t mut; int number=0, i;

void *thread1() {

printf (\

for (i = 0; i < MAX; i++) {

printf(\ pthread_mutex_lock(&mut); number++;

pthread_mutex_unlock(&mut); sleep(2); }

printf(\主函数在等我完成任务吗?\\n\ pthread_exit(NULL); }

void *thread2() {

printf(\

for (i = 0; i < MAX; i++)

{

printf(\ pthread_mutex_lock(&mut); number++;

pthread_mutex_unlock(&mut); sleep(3); }

printf(\主函数在等我完成任务吗?\\n\ pthread_exit(NULL); }

void thread_create(void) {

int temp;

memset(&thread, 0, sizeof(thread)); //comment1 /*创建线程*/

if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0) //comment2

printf(\线程1创建失败!\\n\ else

printf(\线程1被创建\\n\

if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0) //comment3

printf(\线程2创建失败\ else

printf(\线程2被创建\\n\}

void thread_wait(void) {

/*等待线程结束*/

if(thread[0] !=0) { //comment4 pthread_join(thread[0],NULL); printf(\线程1已经结束\\n\ }

if(thread[1] !=0) { //comment5 pthread_join(thread[1],NULL); printf(\线程2已经结束\\n\ } }

int main()

{

/*用默认属性初始化互斥锁*/ 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

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));

第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。这里,我们的函数thread不需要参数,所以最后一个参数设为空指针。第二个参数我们也设为空指针,这样将生成默认属性的线程。对线程属性的设定和修改我们将在下一节阐述。当创建线程成功时,函数返回0,若不为0则说明创建线程失败,常见的错误返回代码为EAGAIN和EINVAL。前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法。创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。 3)pthread_join pthread_exit

函数pthread_join用来等待一个线程的结束。函数原型为:

extern int pthread_join __P ((pthread_t __th, void **__thread_return));

第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现。它的函数原型为:

extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));

唯一的参数是函数的返回代码,只要pthread_join中的第二个参数thread_return不是NULL,这个值将被传递给 thread_return。最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join的线程则返回错误代码ESRCH。 在这一节里,我们编写了一个最简单的线程,并掌握了最常用的三个函数pthread_create,

操作系统实验(实验2-5)

实验二进入VI编辑器格式:vi文件名例:visy.cVi编辑器三种工作方式:1.编辑方式:进入VI处于编辑方式2.文本输入方式:在编辑方式下输入a,进入追加方式,输入i,进入插入方式3.命令方式:在输入方式下,按Esc键,由文本输入转向编辑方式,输入冒号:进入命令方式4.退出vi:wq写文
推荐度:
点击下载文档文档为doc格式
7iw6v3cxnj1x2cx44e354ncj33s24s019na
领取福利

微信扫码领取福利

微信扫码分享