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

进程(线程)同步和互斥实验报告操作系统实验报告课程名称操作系统实验名称进程(线程)的同步与互斥成绩学生姓名作业君专业软件工程班级、学号同组者姓名无实验日期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、记录生产者和消费者的同步执行过程。
实验1编程实现进程同步和互斥

实验1编程实现进程同步和互斥进程(线程)同步和互斥是操作系统中非常重要的概念,它们用于控制多个进程(线程)之间的访问顺序,以确保数据的一致性和正确性。
在本文中,我们将详细介绍进程(线程)同步和互斥的概念,并通过编程实现来说明它们的具体应用。
1.进程(线程)同步的概念进程(线程)同步是指多个进程(线程)之间按照一定的顺序访问共享的资源,以避免竞争条件(race condition)和数据不一致的问题。
在并发环境下,多个进程(线程)同时访问共享的资源时,可能会遇到互相干扰的情况,导致程序的执行结果出现错误。
2.进程(线程)互斥的概念进程(线程)互斥是指在同一时间只能有一个进程(线程)对共享资源进行访问,其他进程(线程)必须等待当前进程(线程)释放资源后才能访问。
通过引入互斥机制,可以避免多个进程(线程)同时对共享资源进行写操作,从而保证数据的一致性和正确性。
3.进程(线程)同步和互斥的实现在实际编程中,可以通过各种同步和互斥机制来实现进程(线程)同步和互斥。
常见的机制有信号量(Semaphore)、互斥锁(Mutex)、条件变量(Condition Variable)等。
下面我们将通过一个简单的编程实例来演示如何使用信号量和互斥锁实现进程(线程)同步和互斥。
假设有两个线程,线程A负责打印奇数,线程B负责打印偶数,要求线程A和线程B交替打印1-100的数字。
我们可以使用互斥锁来控制两个线程的访问顺序,使用信号量来控制线程A和线程B的打印顺序。
首先,我们定义一个全局变量num,用来记录当前需要打印的数字。
定义一个互斥锁mutex,用来保护对num的访问。
定义一个信号量sem,用来控制线程A和线程B的打印顺序。
初始时,num为1,mutex为未锁定状态,sem的初始值为0。
线程A的处理函数如下:```void* threadA(void* arg)while (num <= 100)//等待信号量semsem_wait(&sem);//加锁pthread_mutex_lock(&mutex);//打印奇数if (num <= 100)printf("%d\n", num);num += 2;}//解锁pthread_mutex_unlock(&mutex);//发送信号量给线程Bsem_post(&sem);}return NULL;```线程B的处理函数如下:```void* threadB(void* arg)while (num <= 100)//等待信号量semsem_wait(&sem);//加锁pthread_mutex_lock(&mutex);//打印偶数if (num <= 100)printf("%d\n", num);num += 2;}//解锁pthread_mutex_unlock(&mutex);//发送信号量给线程Asem_post(&sem);}return NULL;```在主函数中创建两个线程,并执行线程:```int maipthread_t tidA, tidB;//初始化互斥锁pthread_mutex_init(&mutex, NULL);//初始化信号量sem_init(&sem, 0, 1);//创建线程Apthread_create(&tidA, NULL, threadA, NULL); //创建线程Bpthread_create(&tidB, NULL, threadB, NULL);//等待线程A结束pthread_join(tidA, NULL);//等待线程B结束pthread_join(tidB, NULL);//销毁互斥锁pthread_mutex_destroy(&mutex);//销毁信号量sem_destroy(&sem);return 0;```通过运行以上代码,我们可以看到线程A和线程B会交替打印1-100的数字,实现了进程(线程)的同步和互斥。
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] 分别用于管道文件的读和写操作。
操作系统实验报告_进程和线程

回答思考题的答案)
一、进程的创建
下面这个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*/
进程的同步与互斥实验报告

进程的同步与互斥实验报告1.实验目的进程(线程)的同步与互斥是操作系统中非常重要的概念,本实验旨在通过实际操作,加深对这些概念的理解和掌握。
通过编写多个进程(线程),并在其间进行同步与互斥操作,验证同步与互斥的实际效果。
2.实验环境本实验在Linux系统下进行,使用C/C++语言编程。
3.实验内容3.1同步在实验中,我们编写了两个进程A和B,这两个进程需要按照特定的顺序执行。
为了实现同步,我们使用信号量机制来确保进程A和B按照正确的顺序执行。
3.2互斥在实验中,我们编写了多个进程C和D,这些进程需要同时对一个共享资源进行访问。
为了实现互斥,我们使用互斥锁机制来确保同一时刻只有一个进程访问共享资源。
4.实验过程4.1同步实验编写进程A和进程B的代码,使用信号量机制实现同步。
进程A先运行,然后通过信号量唤醒进程B,进程B再开始执行。
通过观察进程的运行顺序,验证同步机制是否起作用。
4.2互斥实验编写进程C和进程D的代码,使用互斥锁机制实现互斥。
进程C和进程D同时对一个共享资源进行访问,通过互斥锁来确保同一时刻只有一个进程访问共享资源。
观察进程的输出结果,验证互斥机制是否起作用。
5.实验结果5.1同步实验结果进程A开始执行进程A执行完毕进程B开始执行进程B执行完毕5.2互斥实验结果进程C开始执行进程C访问共享资源进程C执行完毕进程D开始执行进程D访问共享资源进程D执行完毕6.实验分析通过上述结果可以看出,同步实验中进程A和进程B按照正确的顺序执行,证明了同步机制的有效性。
互斥实验中进程C和进程D能够正确地交替访问共享资源,证明了互斥机制的有效性。
7.实验总结通过本次实验,我深刻理解了进程(线程)的同步与互斥,并通过实际操作加深了对这些概念的理解。
同步和互斥是操作系统中非常重要的概念,对于应对资源竞争和提高程序性能具有重要意义。
在实际开发中,我们应该合理使用同步和互斥机制,以确保程序的正确性和并发执行的效率。
操作系统实验题

1、在操作系统中,进程与线程的主要区别是什么?A. 进程是资源分配的基本单位,线程是处理器调度的基本单位B. 进程和线程都是资源分配和处理器调度的基本单位C. 线程是资源分配的基本单位,进程是处理器调度的基本单位D. 进程和线程都不涉及资源分配问题(答案:A)2、以下哪种调度算法可能会导致饥饿问题?A. 先来先服务(FCFS)B. 短作业优先(SJF)C. 时间片轮转(Round Robin)D. 优先级调度(非抢占式)(答案:B)3、在操作系统的存储管理中,分段存储管理方式的主要目的是?A. 提高内存利用率B. 实现内存保护C. 方便用户编程D. 提高程序运行速度(答案:C)4、关于死锁,以下哪个说法是正确的?A. 死锁是指多个进程因竞争资源而无限期等待的现象B. 死锁只可能发生在多道批处理系统中C. 死锁发生时,系统中一定存在多个进程同时处于就绪状态D. 预防死锁的方法之一是破坏“请求和保持”条件,即要求进程一次性申请所有所需资源(答案:A,注:同时D也是预防死锁的一种方法,但题目要求选择正确说法,A更直接描述了死锁的定义)5、在操作系统的文件系统中,目录结构的主要作用是?A. 实现文件的按名存取B. 提高文件存储的效率C. 增强文件系统的安全性D. 便于用户对文件进行备份(答案:A)6、下列哪一项不是虚拟内存技术的优点?A. 扩大内存容量B. 提高内存利用率C. 简化内存管理D. 加快程序运行速度(在某些情况下可能因换页开销而减慢)(答案:D)7、在操作系统的设备管理中,缓冲区的设置主要是为了?A. 提高设备利用率B. 缓和CPU与I/O设备之间速度不匹配的矛盾C. 实现设备的即插即用D. 减少I/O操作的次数(答案:B)8、关于操作系统的中断机制,以下哪个说法是错误的?A. 中断是由硬件或软件发出的,用于请求CPU处理的事件B. 中断处理过程中,CPU会暂停当前程序的执行,转而执行中断处理程序C. 中断向量表是存储中断处理程序入口地址的表D. 在所有情况下,中断处理程序的执行优先级都高于当前正在运行的程序(答案:D,注:中断处理程序的优先级通常较高,但并非在所有情况下都绝对高于所有正在运行的程序,特别是在某些实时系统中可能有更复杂的优先级策略)。
操作系统实验一(杨婷婷)

实验一熟悉Windows2000/XP中的进程和线程一、实验目的1、熟悉Windows2000/XP中任务管理器的使用。
2、通过任务管理器识别操作系统中的进程和线程的相关信息。
3、掌握利用spy++.exe来察看Windows中各个任务的更详细信息。
二、实验理论基础及教材对应关系1、实验理论基础:(1)操作系统中的进程和线程的概念;(2)进程PCB的各项指标含意;2、本实验内容主要对应于教材第2章。
三、实验内容与步骤1、启动操作系统自带的任务管理器:方法:直接按组合键Ctrl+Alt+Del,或者是在点击任务条上的“开始”“运行”,并输入“taskmgr.exe”。
如下图所示:2、调整任务管理器的“查看”中的相关设置,显示关于进程的以下各项信息,并完成下表(填满即可):表一:统计进程的各项主要信息3、从桌面启动办公软件“Word”,在任务管理器中找到该软件的登记,并将其结束掉。
再从任务管理器中分别找到下列程序:winlogon.exe、lsass.exe、csrss.exe、smss.exe,试着结束它们,观察到的反应是,原因是。
4、在任务管理器中找到进程“explorer.exe”,将之结束掉,并将桌面上你打开的所有窗口最小化,看看你的计算机系统起来什么样的变化、得到的结论是(说出explorer.exe进程的作用)。
5、运行“spy++.exe”应用软件,点击按钮“”,切换到进程显示栏上,查看进程“explorer.exe”的各项信息,并填写下表:表二:统计线程的各项信息进程:explorer.exe 中的各个线程6、注意某些线程前有“+”,如图所示:,说明二者之间的差异是。
四、实验材料的提交与成绩评定lsass.exe 系统进程,用于微软Windows系统的安全机制。
services.exe 微软Windows操作系统的一部分。
用于管理启动和停止服务。
winlogon.exe Windows 用户登陆程序,管理用户登录和退出。
大学计算机实验报告答案

一、实验目的1. 理解操作系统基本概念和功能。
2. 掌握进程和线程的基本知识。
3. 学习进程调度和同步机制。
4. 熟悉操作系统实验环境。
二、实验环境1. 操作系统:Windows 102. 编程语言:C/C++3. 开发环境:Visual Studio 2019三、实验内容1. 进程和线程的创建与终止2. 进程调度算法(先来先服务、短作业优先、轮转)3. 线程同步机制(互斥锁、条件变量、信号量)四、实验步骤1. 进程和线程的创建与终止(1)创建进程使用函数`fork()`创建子进程,实现进程的创建。
```c#include <unistd.h>#include <stdio.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork error");return 1;} else if (pid == 0) {// 子进程printf("I am child process, PID: %d\n", getpid()); // 执行子进程任务} else {// 父进程printf("I am parent process, PID: %d\n", getpid()); // 等待子进程结束wait(NULL);}return 0;}```(2)创建线程使用函数`pthread_create()`创建线程,实现线程的创建。
```c#include <pthread.h>#include <stdio.h>void thread_func(void arg) {printf("Thread ID: %ld\n", pthread_self());return NULL;}int main() {pthread_t tid;if (pthread_create(&tid, NULL, thread_func, NULL) != 0) { perror("pthread_create error");return 1;}// 等待线程结束pthread_join(tid, NULL);return 0;}```(3)终止进程和线程使用函数`exit()`和`pthread_exit()`终止进程和线程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验:进程与线程
一、实验目的
通过函数调用掌握进程之间的通信。
体会线程的存在,了解线程与进程的关系。
二、实验环境
PC+Win7操作系统
三、实验方法和实验步骤
1.准备工作
打开VC++6.0环境。
2.在程序编辑区内输入程序,实现两个数互换。
3. 在VC环境下建立一个控制台应用程序P1。
系统启动一个进程(因为支持线程,OS会在进程中主动创建一个主线程)来运行该程序。
输出该进程的ID号、以及该进程下面主线程的ID号。
多运行几次,观察结果。
四、实验结果
补充:在VC环境下建立一个控制台应用程序P1。
系统启动一个进程(因为支持线程,OS会在进程中主动创建一个主线程)来运行该程序。
在进程中,我们自己再创建一个子线程(子线程1),该子线程做的事情很简单,就是让它不停地输出如下信息:
子线程1正在运行第1次,其进程的ID号=~, 子线程1的ID号=~
子线程1正在运行第2次,其进程的ID号=~, 子线程1的ID号=~。
子线程1正在运行第20次,其进程的ID号=~, 子线程1的ID号=~
只要启动了一个子线程,实际上系统中是主线程和子线程1在并发执行。
主线程的功能是输出这样形式的内容:
主线程正在运行第1次,其进程的ID号=~,主线程的ID号=~
主线程正在运行第2次,其进程ID号=~, 主线程的ID号=~。
主线程正在运行第20次,其进程ID号=~, 主线程的ID号=~
多运行几次,观察主线程和子线程并发调动的次序。
每次调度都一样吗?为什么?进程ID、主线程ID和子线程ID每次都一样吗?
体会操作系统中并发的异步性。
程序代码如下:
#include<stdio.h>
#include<afxmt.h>
DWORD WINAPI Thread1(LPVOID lpparameter){
int i;
for(i=1;i<=20;i++){
printf("子线程1在运行中,它正在运行第%d times,所属进程的ID号=%ld, 本线程的ID号=%ld\n",i,GetCurrentProcessId(),GetCurrentThreadId());}
return 0;}
int main(){
int j;
printf("一个进程在运行中\n");
printf("主线程在运行中\n");
HANDLE hThread1=CreateThread(NULL,0,Thread1,NULL,0,NULL);
for(j=1;j<=20;j++){
printf("主线程正在运行第%d次;进程的ID号=%ld,线程ID号=%ld\n", j,GetCurrentProcessId(),GetCurrentThreadId());
Sleep(500); }
return 0; }
多次运行的结果显示,每次调度是不一样的,因为操作系统中程序并发运行时的异步性原则,进程ID、主线程ID和子线程ID每次也都是不一样的。
在上面实验的基础上,再创建一个子线程2,子线程2也如线程1一样输出,只是线程1改为线程2而已。
即,此时在计算机系统中形成主线程、线程1、线程2一起并发的阵势。
多运行几次,观察线程的调度情况,看看每次调度执行的结果一样不一样?
体会计算机系统中线程并发的异步性。
代码如下所示:
#include<stdio.h>
#include<afxmt.h>
DWORD WINAPI Thread1(LPVOID lpparameter){
int i;
for(i=1;i<=10;i++){
printf("子线程1在运行中,它正在运行第%d times,所属进程的ID 号=%ld,本线程的ID号=%ld\n",i,GetCurrentProcessId(),GetCurrentThreadId());
}
return 0;
}
DWORD WINAPI Thread2(LPVOID lpparameter){
int i;
for(i=1;i<=10;i++){
printf("子线程2在运行中,它正在运行第%d times,所属进程的ID 号=%ld,本线程的ID号=%ld\n",i,GetCurrentProcessId(),GetCurrentThreadId());
}
return 0;
}
int main(){
int j;
printf("一个进程在运行中\n");
printf("主线程在运行中\n");
HANDLE hThread1=CreateThread(NULL,0,Thread1,NULL,0,NULL);
HANDLE hThread2=CreateThread(NULL,0,Thread2,NULL,0,NULL);
for(j=1;j<=10;j++){
printf("主线程正在运行第%d次;进程的ID号=%ld,线程ID号=%ld\n", j,GetCurrentProcessId(),GetCurrentThreadId());
Sleep(500);
}
return 0;
}
多次运行的结果显示,每次调度执行是不一样的,因为计算机系统中线程运行时并发的异步性原则。
一个主线程一个子线程时,程序运行一次时,进程ID相同,主线程ID和子线程ID不相同,但是主线程无论允许多少次,主线程的ID都是一样的,子线程也是一样。
多运行几次程序时,每次的进程ID不相同。
一个主线程两
个子线程时,程序运行一次时,进程ID相同,主线程ID和子线程ID不相同,但是主线程无论允许多少次,主线程的ID都是一样的,两个子线程ID却不是一样的。
多运行几次程序时,每次的进程ID不相同。