操作系统实验报告_进程和线程

合集下载

操作系统实验报告进程管理

操作系统实验报告进程管理

操作系统实验报告进程管理操作系统实验报告:进程管理引言操作系统是计算机系统中的核心软件,负责管理计算机的硬件资源和提供用户与计算机之间的接口。

进程管理是操作系统的重要功能之一,它负责对计算机中运行的各个进程进行管理和调度,以保证系统的高效运行。

本实验报告将介绍进程管理的基本概念、原理和实验结果。

一、进程管理的基本概念1. 进程与线程进程是计算机中正在运行的程序的实例,它拥有独立的内存空间和执行环境。

线程是进程中的一个执行单元,多个线程可以共享同一个进程的资源。

进程和线程是操作系统中最基本的执行单位。

2. 进程状态进程在运行过程中会经历不同的状态,常见的进程状态包括就绪、运行和阻塞。

就绪状态表示进程已经准备好执行,但还没有得到处理器的分配;运行状态表示进程正在执行;阻塞状态表示进程由于某些原因无法继续执行,需要等待某些事件的发生。

3. 进程调度进程调度是操作系统中的一个重要任务,它决定了哪个进程应该获得处理器的使用权。

常见的调度算法包括先来先服务(FCFS)、最短作业优先(SJF)和时间片轮转等。

二、进程管理的原理1. 进程控制块(PCB)PCB是操作系统中用于管理进程的数据结构,它包含了进程的各种属性和状态信息,如进程标识符、程序计数器、寄存器值等。

通过PCB,操作系统可以对进程进行管理和控制。

2. 进程创建与撤销进程的创建是指操作系统根据用户的请求创建一个新的进程。

进程的撤销是指操作系统根据某种条件或用户的请求终止一个正在运行的进程。

进程的创建和撤销是操作系统中的基本操作之一。

3. 进程同步与通信多个进程之间可能需要进行同步和通信,以实现数据共享和协作。

常见的进程同步与通信机制包括互斥锁、信号量和管道等。

三、实验结果与分析在本次实验中,我们使用了一个简单的进程管理模拟程序,模拟了进程的创建、撤销和调度过程。

通过该程序,我们可以观察到不同调度算法对系统性能的影响。

实验结果显示,先来先服务(FCFS)调度算法在一些情况下可能导致长作业等待时间过长,影响系统的响应速度。

进程(线程)同步和互斥实验报告

进程(线程)同步和互斥实验报告

进程(线程)同步和互斥实验报告操作系统实验报告课程名称操作系统实验名称进程(线程)的同步与互斥成绩学生姓名作业君专业软件工程班级、学号同组者姓名无实验日期2021一、实验题目: : 进程(线程)的同步与互斥二、实验目的:自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的 PCB 内容、组织的变化,理解进程与其 PCB 间的一一对应关系。

1.掌握基本的同步与互斥算法,理解生产者消费者模型。

2.学习使用 Windows 中基本的同步对象,掌握相关 API 的使用方法。

3.了解 Windows 中多线程的并发执行机制,实现进程的同步与互斥三、实验内容与要求:1.实验内容以生产者/消费者模型为依据,在 Windows 环境下创建一个控制台进程,在该进程中创建 n 个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。

2.实验要求学习并理解生产者/消费者模型及其同步/互斥规则;学习了解 Windows 同步对象及其特性;熟悉实验环境,掌握相关 API 的使用方法;设计程序,实现生产者/消费者进程(线程)的同步与互斥;四、算法描述(含数据结构定义)或流程图#include <Windows.h> #include <iostream> #include<stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std;#define MA__THREAD_NUM 64//最大线程数 #define INTE_PER_SEC 1000//延迟时间的毫秒值 const int SIZE_OF_BUFFER = 10;//缓冲区长度 int ProductID = 0;//产品号 int ConsumeID = 0;//将被消耗的产品号 int in = 0;//产品进缓冲区时的缓冲区下标 int out = 0;//产品出缓冲区时的缓冲区下标 bool running = true;//判断程序能否继续执行的逻辑值 intg_buffer[SIZE_OF_BUFFER];//缓冲区是个循环队列 HANDLE g_hMute_;//公有信号量,用于线程间的互斥 HANDLEg_hFullSemaphore;//生产者的私有信号量,当缓冲区满时迫使生产者等待HANDLE g_hEmptySemaphore;//消费者的私有信号量,当缓冲区空时迫使消费者等待//定义一个结构体用于存储线程的信息 struct ThreadInfo {int serial;//线程号char entity;//线程类别(生产者或消费者)double delay;//等待时间double persist; //操作时间 };//生产者 void Producer(void_p) {//定义变量用于存储当前线程的信息DWORD m_delay;DWORD m_persist;int m_serial;//从参数中获得信息m_serial = ((ThreadInfo_)(p))->serial;m_delay = (DWORD)(((ThreadInfo_)(p))->delay _INTE_PER_SEC);m_persist = (DWORD)(((ThreadInfo_)(p))->persist _INTE_PER_SEC);while (running){//P 操作cout << “生产者线程” << m_serial << “ 请求生产.” << endl;WaitForSingleObject(g_hEmptySemaphore, INFINITE);cout << “生产者线程” << m_serial << “ 请求独占缓冲区.” << endl;WaitForSingleObject(g_hMute_, INFINITE);Sleep(m_delay);//延迟等待//生产一个产品cout << “生产者线程”<< m_serial << “ 生产” << ++ProductID << “ 号产品成功.” << endl;cout << “生产者线程” << m_serial << “ 请求将产品” << ProductID << “ 投入缓冲区.” << endl;//把新生产的产品放入缓冲区g_buffer[in] = ProductID;in = (in +1)%SIZE_OF_BUFFER;Sleep(m_persist);//操作等待cout << “生产者线程” << m_serial << “ 将产品” << ProductID << “ 投入缓冲区中成功.” << endl;//输出缓冲区当前的状态cout << “____________________________” << endl<< “\n 当前缓冲区情况如图(■代表已有产品,□代表没有产品):” << endl;for (int i = 0;i < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << “■”;elsecout << “□”;}cout << “\n\n____________________________\n” << endl;//V 操作ReleaseMute_(g_hMute_);ReleaseSemaphore(g_hFullSemaphore, 1, NULL);} }//消费者 void Consumer(void_p) {DWORD m_delay;DWORD m_persist;int m_serial;//从参数中获得信息m_serial = ((ThreadInfo_)(p))->serial;m_delay = (DWORD)(((ThreadInfo_)(p))->delay _INTE_PER_SEC);m_persist = (DWORD)(((ThreadInfo_)(p))->persist _INTE_PER_SEC);while (running){//P 操作cout << “消费者线程” << m_serial << “ 请求消费.” << endl;WaitForSingleObject(g_hFullSemaphore, INFINITE);cout << “消费者线程” << m_serial << “ 请求独占缓冲区.” << endl;WaitForSingleObject(g_hMute_,INFINITE);Sleep(m_delay); //延迟等待//从缓冲区中取出一个产品cout << “消费者线程” << m_serial << “ 请求取出一个产品.” << endl;ConsumeID = g_buffer[out];g_buffer[out] = 0;out = (out + 1) % SIZE_OF_BUFFER;cout << “消费者线程” << m_serial << “ 取出产品” << ConsumeID << “ 成功.” << endl;//消耗一个产品cout << “消费者线程” << m_serial << “ 开始消费消费产品” << ConsumeID << “.” << endl;Sleep(m_persist);cout << “消费者线程” << m_serial << “ 消费产品” << ConsumeID << “ 成功.” << endl;//输出缓冲区当前的状态cout << “____________________________” << endl<< “\n 当前缓冲区情况如图:” << endl;for (int i = 0;i < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << “■”;elsecout << “□”;}cout << “\n\n____________________________\n” << endl;//V 操作ReleaseMute_(g_hMute_);ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);} }void prod_cons {//创建互斥信号量g_hMute_ = CreateMute_(NULL, FALSE, NULL);//创建同步信号量g_hEmptySemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER, SIZE_OF_BUFFER, NULL);g_hFullSemaphore = CreateSemaphore(NULL, 0,SIZE_OF_BUFFER, NULL);srand((unsigned)time(NULL));//以时间函数为种子const unsigned short THREADS_COUNT = rand % 5 + 5; //总的线程数(随机生成)//线程对象的数组HANDLE hThreads[MA__THREAD_NUM];ThreadInfo thread_info[MA__THREAD_NUM];DWORD thread_ID; //线程 IDint num = 0;//临时变量,用于循环语句cout << “系统开始模拟,并自动生成模拟数据...” << endl;system(“pause”); //暂停确认开始执行cout << “线程总数:” << THREADS_COUNT << endl;//循环随机生成各个线程的信息while (num != THREADS_COUNT){thread_info[num].serial = num + 1;if (rand % 2 == 1)thread_info[num].entity = "P";elsethread_info[num].entity = "C";thread_info[num].delay = rand % 5 + 1;thread_info[num].persist = rand % 6 + 2;num++;}cout << “\n 系统生成数据结束,模拟数据如下:” << endl<< “线程号线程类别延迟时间操作时间” << endl;for (int _ = 0;_ < THREADS_COUNT;_++)cout << “” << thread_info[_].serial << “\t”<< “” << thread_info[_].entity << “\t”<< “” << thread_info[_].delay << “\t\t”<< “” << thread_info[_].persist << endl;cout << “\n\n==================生产者-消费者开始==================\n” << endl;//创建线程for (int i = 0;i < THREADS_COUNT;i++){//创建生产者线程if (thread_info[i].entity == "P")hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Producer), ;thread_info[i], 0, ;thread_ID);//创建消费者线程elsehThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Consumer), ;thread_info[i], 0, ;thread_ID);}while (running){if (getchar){//按回车后终止程序运行running = false;}}cout << “系统模拟结束...” << endl; } int main {cout << “\n==================生产者-消费者模拟==================\n” << endl;prod_cons; }五、实验过程1、记录生产者和消费者的同步执行过程。

linux进程与线程通讯实验报告

linux进程与线程通讯实验报告

linux 进程与线程通讯实验报告操作系统实验一进程与线程—Linux 进程与线程通讯实验报告操作系统课程设计任务书篇二: 操作系统实验Linux 进程与线程通讯Linux 进程与线程通讯报告人:设计目的1、深刻理解线程和进程的概念2、掌握线程与进程在组成成分上的差别以及与其相适应的通讯方式和应用目标。

设计的内容1、以Linux 系统进程和线程机制为背景,掌握fork() 和clone() 系统调用的2、形式和功能以及与其相适应的高级通讯方式。

由fork 派生的子进程之间通过pipe 通讯,由clone 创建的线程之间通过共享内存通讯,对于后者需要考虑互斥问题。

3、以生产者-消费者问题为例,通过实验理解fork() 和clone() 两个系统调的区别。

程序要求能够创建4 个进程或线程,其中包括两个生产者和两个消费者,生产者和消费者之间能够传递数据。

4、设计准备1、fork 系统调用、pid=fork()创建一个子进程,子进程是父进程的完整复制,正常返回值为非负整数,对于 父进程来说该数大于 0,是子进程的编号 (pid); 对于子进程来说该数为 0。

正是利用反回值的差别可以决定二者不同的后继动作。

2、 clone 系统调用int clone(int (*fn)(void * arg), void *stack, int flags, void * arg);其中 fn 是轻进程所执行的函数, stack 是轻进程所使用的栈, flag 是CLONE_VM, CLONE_FS, CLONE_FILES,LONE_SIGHAND,CLONE_的组合,arg 是调用过程的对应参数。

Clone()的关键是flag 的设定,CLONE_V S 示子进程共享父进程内存,CLONE_F 表示子进程共3、 pipe 系统调用et_val=pipe(fd);参数定义为 int fd[2] 。

创建一个管道文件,返回两个文件描述符 fd[0] 和fd[1] 分别用于管道文件的读和写操作。

操作系统实验实验报告

操作系统实验实验报告

操作系统实验实验报告一、实验目的操作系统是计算机系统中最为关键的核心软件,它管理着计算机的硬件资源和软件资源,为用户提供了一个方便、高效、稳定的工作环境。

本次操作系统实验的目的在于通过实际操作和实践,深入理解操作系统的基本原理和核心概念,掌握操作系统的基本功能和操作方法,提高对操作系统的认识和应用能力。

二、实验环境本次实验使用的操作系统为 Windows 10 专业版,开发工具为Visual Studio 2019,编程语言为 C 和 C++。

实验硬件环境为一台配备Intel Core i7 处理器、16GB 内存、512GB SSD 硬盘的个人计算机。

三、实验内容(一)进程管理实验1、进程创建与终止通过编程实现创建新的进程,并在完成任务后终止进程。

在实验中,我们使用了 Windows API 函数 CreateProcess 和 TerminateProcess 来完成进程的创建和终止操作。

通过观察进程的创建和终止过程,深入理解了进程的生命周期和状态转换。

2、进程同步与互斥为了实现进程之间的同步与互斥,我们使用了信号量、互斥量等同步对象。

通过编写多线程程序,模拟了多个进程对共享资源的访问,实现了对共享资源的互斥访问和同步操作。

在实验中,我们深刻体会到了进程同步与互斥的重要性,以及不正确的同步操作可能导致的死锁等问题。

(二)内存管理实验1、内存分配与释放使用 Windows API 函数 VirtualAlloc 和 VirtualFree 进行内存的分配和释放操作。

通过实验,了解了内存分配的不同方式(如堆分配、栈分配等)以及内存释放的时机和方法,掌握了内存管理的基本原理和操作技巧。

2、内存分页与分段通过编程模拟内存的分页和分段管理机制,了解了内存分页和分段的基本原理和实现方法。

在实验中,我们实现了简单的内存分页和分段算法,对内存的地址转换和页面置换等过程有了更深入的理解。

(三)文件系统实验1、文件操作使用 Windows API 函数 CreateFile、ReadFile、WriteFile 等进行文件的创建、读取和写入操作。

操作系统实验报告_进程和线程

操作系统实验报告_进程和线程

回答思考题的答案)
一、进程的创建
下面这个C程序展示了UNIX系统中父进程创建子进程及各自分开活 动的情况。
实验指导
fork( ) 创建一个新进程。
系统调用格式:
参数定义:
pid=fork( )
int fork( ) fork( )返回值意义如下: 0:在子进程中,pid变量保存的fork( )返回值为0,表示当前进程是 子进程。
3、编译和运行
$gcc process.c –o processs
4、运行
$./process 程序运行截图
5、思考
(1) 系统是怎样创建进程的? (2) 扩展程序,在父进程中输出1到5,在子进程中输出6-
10,要求父子进程并发输出;记录实验结果,并给出简 单分析。
6.实验中遇到的问题和解决方法
fprintf(stderr, "Fork Failed"); exit(-1); } else if (pid == 0) { /* child process */ execlp( "/bin/ls", "ls",NULL); } else {/* parent process */ /* parent will wait for the child to complete */ wait(NULL); printf( "Child Complete" ); exit(0); } }
4、思考
(1)程序运行后,进程thread中有几个线程存在? (2)为什么前后两次运行结果不一样?
答(1) (2)
5.实验中遇到的问题和解决方法 运行结果并没有出现预期效果
2、参考程序代码
/*process.c*/

操作系统进程控制实验报告

操作系统进程控制实验报告

操作系统进程控制实验报告一、实验目的操作系统进程控制是操作系统中的重要概念和核心功能之一。

本次实验的目的在于深入理解操作系统中进程的概念、状态及其转换,掌握进程创建、终止、阻塞和唤醒等操作的实现原理和方法,通过实际编程和调试,观察进程的行为和特性,从而提高对操作系统原理的理解和应用能力。

二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C++,开发工具为 Visual Studio 2019。

三、实验原理(一)进程的概念进程是操作系统中进行资源分配和调度的基本单位,它包含了程序代码、数据、堆栈等资源。

进程具有独立性、动态性和并发性等特点。

(二)进程的状态进程的状态通常包括就绪态、运行态和阻塞态。

就绪态表示进程已具备运行条件,等待被调度;运行态表示进程正在 CPU 上执行;阻塞态表示进程因等待某个事件而暂停执行。

(三)进程控制的基本操作1、进程创建:通过系统调用创建新的进程,为其分配资源并初始化。

2、进程终止:当进程完成任务或出现异常时,结束其执行并回收资源。

3、进程阻塞:进程在等待某个事件时,主动进入阻塞态。

4、进程唤醒:当等待的事件发生时,将阻塞的进程唤醒,使其进入就绪态。

四、实验内容与步骤(一)进程创建1、编写 C++程序,使用系统提供的函数创建新的进程。

2、在新进程中执行特定的任务,例如打印输出信息。

```cppinclude <windowsh>include <iostream>int main(){STARTUPINFO si;PROCESS_INFORMATION pi;ZeroMemory(&si, sizeof(si));sicb = sizeof(si);ZeroMemory(&pi, sizeof(pi));//创建新进程if (!CreateProcess(NULL, //应用程序名称"C:\\Path\\To\\Your\\ChildProcessexe",//命令行参数NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)){std::cerr <<"CreateProcess failed Error code: "<<GetLastError()<< std::endl;return 1;}//等待子进程结束WaitForSingleObject(pihProcess, INFINITE);//关闭进程和线程句柄CloseHandle(pihProcess);CloseHandle(pihThread);return 0;}```(二)进程终止1、在创建的进程中设置条件,当满足条件时主动终止进程。

linux进程线程管理实验报告

linux进程线程管理实验报告

linux进程线程管理实验报告————————————————————————————————作者:————————————————————————————————日期:西安郵電學院操作系统LINUX实验报告题目1:进程______题目2:线程管理__题目3:互斥_____系部名称:计算机学院专业名称:软件工程班级:0802学号:04085048学生姓名:郭爽乐时间:2010-10-31实验一: 进程管理一.实验目的通过观察、分析实验现象,深入理解进程及进程在调度执行和内存空间等方面的特点,掌握在POSIX 规范中fork和kill系统调用的功能和使用。

二.实验要求2.1 实验环境要求1. 硬件(1) 主机:Pentium III 以上;(2) 内存:128MB 以上;(3) 显示器:VGA 或更高;(4) 硬盘空间:至少100MB 以上剩余空间。

2. 软件Linux 操作系统,内核2.4.26 以上,预装有X-Window 、vi、gcc、gdb 和任意web 浏览器。

2.2 实验前的准备工作学习man 命令的用法,通过它查看fork 和kill 系统调用的在线帮助,并阅读参考资料,学会fork 与kill 的用法。

复习C 语言的相关内容。

三、实验内容3.1 补充POSIX 下进程控制的残缺版实验程序3.2回答下列问题:1. 你最初认为运行结果会怎么样?2. 实际的结果什么样?有什么特点?试对产生该现象的原因进行分析。

3. proc_number 这个全局变量在各个子进程里的值相同吗?为什么?4. kill 命令在程序中使用了几次?每次的作用是什么?执行后的现象是什么?5. 使用kill 命令可以在进程的外部杀死进程。

进程怎样能主动退出?这两种退出方式哪种更好一些?四、实验结果4.1 补充完全的源程序#include<stdio.h>#include<sys/types.h>#include<unistd.h>#include<signal.h>#include<ctype.h>#define MAX_CHILD_NUMBER 10/* 允许建立的子进程个数最大值 */ #define SLEEP_INTERV AL 1/* 子进程睡眠时间 */int proc_number=0; /* 子进程的编号,从0开始 */void do_something();main(int argc,char *argv[]){int child_proc_number=MAX_CHILD_NUMBER; /* 子进程个数 */ int i,ch;pid_t child_pid;pid_t pid[10]={0};/* 存放每个子进程的id */if(argc>1){child_proc_number=atoi(argv[1]);child_proc_number=(child_proc_number>10)?10:child_proc_number; /* 命令行参数中的第一个参数表示建立几个子进程,最多10个 */ }/*建立child_proc_number个子进程* 子进程要执行* proc_number = i;* do_something();* 父进程把子进程的id保存到pid[i] */for(i=0;i<child_proc_number;i++){child_pid=fork();if(child_pid== -1){perror("creat error!\n");return 1;}else if(child_pid>0)pid[i]=child_pid;else{proc_number=i;do_something();}}/* 让用户选择杀死哪个进程。

操作系统实验三实验报告

操作系统实验三实验报告
三、实验内容
(一)进程创建
编写程序实现创建多个进程,并观察进程的执行情况。通过调用Windows API函数`CreateProcess`来创建新的进程。在创建进程时,设置不同的参数,如进程的优先级、命令行参数等,观察这些参数对进程执行的影响。
(二)进程控制
实现对进程的暂停、恢复和终止操作。使用`SuspendThread`和`ResumeThread`函数来暂停和恢复进程中的线程,使用`TerminateProcess`函数来终止进程。通过控制进程的执行状态,观察系统的资源使用情况和进程的响应。
(一)进程创建实验结果与分析
创建多个进程后,通过任务管理器观察到新创建的进程在系统中运行。不同的进程优先级设置对进程的CPU占用和响应时间产生了明显的影响。高优先级的进程能够更快地获得CPU资源,执行速度相对较快;而低优先级的进程则在CPU资源竞争中处于劣势,可能会出现短暂的卡顿或计一个多进程同步的程序,使用信号量、互斥量等同步机制来协调多个进程的执行。例如,实现一个生产者消费者问题,多个生产者进程和消费者进程通过共享缓冲区进行数据交换,使用同步机制来保证数据的一致性和正确性。
四、实验步骤
(一)进程创建实验步骤
1、打开Visual Studio 2019,创建一个新的C++控制台应用程序项目。
六、实验中遇到的问题及解决方法
(一)进程创建失败
在创建进程时,可能会由于参数设置不正确或系统资源不足等原因导致创建失败。通过仔细检查参数的设置,确保命令行参数、环境变量等的正确性,并释放不必要的系统资源,解决了创建失败的问题。
(二)线程控制异常
在暂停和恢复线程时,可能会出现线程状态不一致或死锁等异常情况。通过合理的线程同步和错误处理机制,避免了这些异常的发生。在代码中添加了对线程状态的判断和异常处理的代码,保证了线程控制的稳定性和可靠性。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3、编译和运行
$gcc process.c –o processs
4、运行
$./process 程序运行截图
5、思考
(1) 系统是怎样创建进程的? (2) 扩展程序,在父进程中输出1到5,在子进程中输出6-
10,要求父子进程并发输出;记录实验结果,并给出简 单分析。
6.实验中遇到的问题和解决方法
>0:在父进程中,pid变量保存的fork( )返回值为子进程的id值(进 程唯一标识符)。
-1:创建失败。 如果fork( )调用成功,它向父进程返回子进程的PID,并向子进程返 回0,即fork( )被调用了一次,但返回了两次。此时OS在内存中建立一 个新进程,所建的新进程是调用fork( )父进程(parent process)的副 本,称为子进程(child process)。子进程继承了父进程的许多特性, 并具有与父进程完全相同的用户级上下文。父进程与子进程并发执行。
当创建线程成功时,函数返回0,若不为0则说明创建线程失败,常见的 错误返回代码为EAGAIN和EINVAL。前者表示系统限制创建新的线 程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非 法。创建线程成功后,新创建的线程则运行参数三和参数四确定的函 数,原来的线程则继续运行下一行代码。 函数pthread_join用来等待一个线程的结束。函数原型为: extern int pthread_join __P ((pthread_t __th, void **__thread_return));
2、参考程序代码
/* thread.c*/ #include <stdio.h> #include <pthread.h> void thread(void) { int i; for(i=0;i<3;i++) printf("This is a pthread.\n"); } int main(int argc,char *argv[]) { pthread_t id; int i,ret; ret=pthread_create(&id,NULL,(void *) thread,NULL); if(ret!=0){ printf ("Create pthread error!\n"); exit (1);
} for(i=0;i<3;i++) printf("This is the main process.\n"); pthread_join(id,NULL); retu程序:
gcc example1.c -lpthread -o example1
-lpthread:使用线程库
计算机科学与软件学院
操作系统上机实验报告
学生姓名: 学号: 班级:班 实验日期: 2014.4.17
实验名称:进程和线程
实验目的:理解unix/Linux下进程和线程的创建、并发执行过程。
实验内容:
1.进程的创建
2.多线程应用
实验步骤及分析:(此部分为关键内容:要求整理实验主要步骤,
总结编写实验过程中遇到哪些问题,如何解决的,若未解决也应总结,
运行example1,得到如下结果: This is the main process. This is a pthread. This is the main process. This is the main process. This is a pthread. This is a pthread. 再次运行,可能得到如下结果: This is a pthread. This is the main process. This is a pthread. This is the main process. This is a pthread. This is the main process. 程序运行截图
fprintf(stderr, "Fork Failed"); exit(-1); } else if (pid == 0) { /* child process */ execlp( "/bin/ls", "ls",NULL); } else {/* parent process */ /* parent will wait for the child to complete */ wait(NULL); printf( "Child Complete" ); exit(0); } }
回答思考题的答案)
一、进程的创建
下面这个C程序展示了UNIX系统中父进程创建子进程及各自分开活 动的情况。
1、实验指导
fork( ) 创建一个新进程。
系统调用格式:
参数定义:
pid=fork( )
int fork( ) fork( )返回值意义如下: 0:在子进程中,pid变量保存的fork( )返回值为0,表示当前进程是 子进程。
第一个参数为被等待的线程标识符,第二个参数为一个用户定义的 指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞 的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返 回时,被等待线程的资源被收回。
一个线程的结束有两种途径,一种是象我们上面的例子一样,函数 结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit 来实现。它的函数原型为: extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__)); 唯一的参数是函数的返回代码,只要pthread_join中的第二个参数 thread_return不是NULL,这个值将被传递给 thread_return。
二、多线程应用 编写unix/Linux下的多线程程序,需要使用头文件pthread.h,连接时
需要使用库libpthread.a。下面是一个最简单的多线程程序 example1.c。
1.实验指导
下面的示例中,要使用到两个函数,pthread_create和pthread_join, 并声明了一个pthread_t型的变量。 函数pthread_create用来创建一个线程,它的原型为: extern int pthread_create __P ((pthread_t *__thread, __const pthread_attr_t *__attr,void *(*__start_routine) (void *), void *__arg)); 第一个参数为指向线程标识符的指针,第二个参数用来设置线程属 性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数 的参数。这里,我们的函数thread不需要参数,所以最后一个参数设为 空指针。第二个参数我们也设为空指针,这样将生成默认属性的线程。
4、思考
(1)程序运行后,进程thread中有几个线程存在? (2)为什么前后两次运行结果不一样?
答(1) (2)
5.实验中遇到的问题和解决方法 运行结果并没有出现预期效果
2、参考程序代码
/*process.c*/
#include <stdio.h> #include <sys/types.h> main(int argc,char *argv[]) {
int pid; /* fork another process */ pid = fork(); if (pid < 0) { /* error occurred */
相关文档
最新文档