[cpp]view plain copy

/*

每一个程序相当于一个进程,而一个进程之中可以有多个线程

*/

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<windows.h>

#include<stdlib.h>

#include<process.h>       //进程函数

void run(void *p)

{

int *temp = (int *)p;

char ch[50];

sprintf(ch, "线程%d启动", *temp);

MessageBoxA(0, ch, "多线程", 0);

}

void main()

{

for (int i = 0; i < 5; i++)

{

//第一个参数为函数的地址,第二个参数为栈的大小,0代表默认大小,第三个参数为函数的实参,必须为void*类型

_beginthread(run, 0, &i);   //多线程调用函数

Sleep(1000);

}

system("pause");

}

运行结果:开启五个线程!

2 阻塞式进程

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<stdlib.h>

#include<windows.h>

#include<process.h>

void changeCMDtitle(void *p)

{

int i = 1;

char str[20];

while (1)

{

Sleep(1000);

sprintf(str, "title 程序运行的第%d秒", i);

system(str);

i++;

}

}

void endMultiThread(void *p)

{

int *px = (int *)p;     //指针转换

int i = 0;

while (1)

{

if (i > 5)

{

printf("%d\t%d\n", i, *px);

_endthread();   //结束线程,该程序执行完毕之后退出,如果是return的话,直接退出

}

Sleep(1000);

i++;

}

}

void main()

{

_beginthread(changeCMDtitle, 0, NULL);

for (int i = 0; i < 5; i++)

{

HANDLE hd = _beginthread(endMultiThread, 0, &i);        //hd相当于线程编号

//没有等待的情况下为多线程,五个线程同时进行

WaitForSingleObject(hd, INFINITE);      //等待模式,第二个参数代表无限期等待,for循环里边相当于单线程

Sleep(1000);                                //有Sleep的情况下每隔一秒endMultiThread函数相继关闭,否则,同时关闭

}

system("pause");

}

运行结果:WaitForSingleObject为阻塞式进程,当且仅当当前进程执行完毕之后才会进入下一进程,否则,无限等待。

3 进程和线程之间的区别和联系

进程,是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竟争计算机系统资源的基本单位。每一个进程都有一个自己的地址空间,即进程空间或(虚空间)。进程空间的大小 只与处理机的位数有关,一个 16 位长处理机的进程空间大小为 216 ,而 32 位处理机的进程空间大小为 232 。进程至少有 5 种基本状态,它们是:初始态,执行态,等待状态,就绪状态,终止状态。

线程,在网络或多用户环境下,一个服务器通常需要接收大量且不确定数量用户的并发请求,为每一个请求都创建一个进程显然是行不通的,——无论是从系统资源开销方面或是响应用户请求的效率方面来看。因此,操作系统中线程的概念便被引进了。线程,是进程的一部分,一个没有线程的进程可以被看作是单线程的。线程有时又被称为轻权进程或轻量级进程,也是 CPU 调度的一个基本单位。

 
说到这里,我们对进程与线程都有了一个大体上的印象,现在开始说说二者大致的区别。

进程的执行过程是线状的,尽管中间会发生中断或暂停,但该进程所拥有的资源只为该线状执行过程服务。一旦发生进程上下文切换,这些资源都是要被保护起来的。这是进程宏观上的执行过程。而进程又可有单线程进程与多线程进程两种。我们知道,进程有 一个进程控制块 PCB ,相关程序段 和 该程序段对其进行操作的数据结构集 这三部分,单线程进程的执行过程在宏观上是线性的,微观上也只有单一的执行过程;而多线程进程在宏观上的执行过程同样为线性的,但微观上却可以有多个执行操作(线程),如不同代码片段以及相关的数据结构集。线程的改变只代表了 CPU 执行过程的改变,而没有发生进程所拥有的资源变化。出了 CPU 之外,计算机内的软硬件资源的分配与线程无关,线程只能共享它所属进程的资源。与进程控制表和 PCB 相似,每个线程也有自己的线程控制表 TCB ,而这个 TCB 中所保存的线程状态信息则要比 PCB 表少得多,这些信息主要是相关指针用堆栈(系统栈和用户栈),寄存器中的状态数据。进程拥有一个完整的虚拟地址空间,不依赖于线程而独立存在;反之,线程是进程的一部分,没有自己的地址空间,与进程内的其他线程一起共享分配给该进程的所有资源。

线程可以有效地提高系统的执行效率,但并不是在所有计算机系统中都是适用的,如某些很少做进程调度和切换的实时系统。使用线程的好处是有多个任务需要处理机处理时,减少处理机的切换时间;而且,线程的创建和结束所需要的系统开销也比进程的创建和结束要小得多。最适用使用线程的系统是多处理机系统和网络系统或分布式系统。

 
1. 线程的执行特性。

线程只有 3 个基本状态:就绪,执行,阻塞。

线程存在 5 种基本操作来切换线程的状态:派生,阻塞,激活,调度,结束。

2. 进程通信。

单机系统中进程通信有 4 种形式:主从式,会话式,消息或邮箱机制,共享存储区方式。

主从式典型例子:终端控制进程和终端进程。

会话式典型例子:用户进程与磁盘管理进程之间的通信。

 

4 进程和线程之间的区别和联系(二)

 
1.定义
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

2.关系
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

3.区别
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
2) 线程的划分尺度小于进程,使得多线程程序的并发性高。
3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
4.优缺点
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

 

5 多线程程序设计的八个规则

 

6 多线程编程实例:

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<stdlib.h>

#include<windows.h>

#include<process.h>

int flag = 1;               //标志位,便于各进程之间进行通信

int *destPtr = NULL;        //所查找元素的目标地址,设置为NULL是为了避免野指针

struct MultiSearch{

int len;                //要查找的长度

int data;               //要查找的数据

int *beg;               //要查找的起始地址

int *sflag;             //标志位,便于各进程之间进行通信

int **addr;             //产地一个指针的地址

int index;              //进程编号

};

void find(void *ptr)

{

struct MultiSearch *pstruct = (struct MultiSearch *)ptr;

for (int *pbeg = pstruct->beg; pbeg != pstruct->beg + pstruct->len; pbeg++)

{

Sleep(30);                              //留出一些时间,让其他线程查找

if (*(pstruct->sflag) == 0)              //判断是否找到,如果找到,则终止程序

{

printf("本线程%d无能,其他线程已经找到。\n", pstruct->index);

return;                             //结束该线程,本线程以后的程序不再执行

}

if (pstruct->data == *pbeg)              //判断该元素是否和查找的元素相等,如果相等,则返回,其他进程也相应结束查找

{

printf("第%d个线程查找到该内容.\n", pstruct->index);

*(pstruct->sflag) = 0;               //标志位设为0;

*(pstruct->addr) = pbeg;         //将找到的地址赋予结构体内的元素

return;                             //结束进行

}

}

printf("本线程%d无能,没有找到该元素。\n", pstruct->index);

return;                                     //正常结束

}

void main()

{

int arr[1000] = { 0 };                      //从1000个数中查找num;

for (int i = 0; i < 1000; i++)               //为数组赋值

arr[i] = i + 1;

int num = 0;

printf("请输入要查找的数字(仅限于0到999的整数类型):");

scanf("%d", &num);

struct MultiSearch ms[10];                  //申请十个结构类型,为避免各个线程之间的数据交叉,使每个线程中的数据都是独立的

for (int i = 0; i < 10; i++)             //创建10个线程进行查找,每个线程查找其中的一百个元素

{

ms[i].beg = arr + i * 100;

ms[i].len = 100;

ms[i].data = num;

ms[i].sflag = &flag;

ms[i].addr = &destPtr;

ms[i].index = i;

_beginthread(find, 0, &ms[i]);

Sleep(50);                              //为创建进程留出时间

}

Sleep(3000);                                //等待查找结束

system("pause");                            //如果主线程结束了,则其他的线程也相应结束了,因此要为主线程预留足够多的时间

printf("\n%p, %d\n", destPtr, *destPtr);    //打印该元素的地址及其该地址所对应的数据

system("pause");

}

 
运行结果:
 

请输入要查找的数字(仅限于0到999的整数类型):888

本线程0无能,没有找到该元素。

第8个线程查找到该内容.

本线程7无能,其他线程已经找到。

本线程4无能,其他线程已经找到。

本线程1无能,其他线程已经找到。

本线程6无能,其他线程已经找到。

本线程3无能,其他线程已经找到。

本线程9无能,其他线程已经找到。

本线程5无能,其他线程已经找到。

本线程2无能,其他线程已经找到。

请按任意键继续. . .

  1. 004CF894, 888
  2. 请按任意键继续. . .

C语言阐述进程和线程的区别的更多相关文章

  1. Linux进程与线程的区别

    进程与线程的区别,早已经成为了经典问题.自线程概念诞生起,关于这个问题的讨论就没有停止过.无论是初级程序员,还是资深专家,都应该考虑过这个问题,只是层次角度不同罢了.一般程序员而言,搞清楚二者的概念, ...

  2. Python之路-python(paramiko,进程和线程的区别,GIL全局解释器锁,线程)

    一.paramiko 二.进程.与线程区别 三.python GIL全局解释器锁 四.线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生 ...

  3. 【Linux】程序、进程和线程的区别

    程序.进程和线程的区别 程序是一组指令及参数的集合,指令按照既定的逻辑控制计算机运行.进程则是运行着的程序,是操作系统执行的基本单位.线程则是为了节省资源而可以在同一个进程中共享资源的一个执行单位. ...

  4. 2018.7.26 进程和线程的区别 &&你对 Java平台的理解

    进程和线程的区别 1.定义 进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程:进程的一个实体,是CPU调度和分派的基本单位,它是比进程更 ...

  5. java核心知识点学习----并发和并行的区别,进程和线程的区别,如何创建线程和线程的四种状态,什么是线程计时器

    多线程并发就像是内功,框架都像是外功,内功不足,外功也难得精要. 1.进程和线程的区别 一个程序至少有一个进程,一个进程至少有一个线程. 用工厂来比喻就是,一个工厂可以生产不同种类的产品,操作系统就是 ...

  6. VC++学习之进程和线程的区别

    VC++学习之进程和线程的区别 一.进程        进程是表示资源分配的基本单位,又是调度运行的基本单位.例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格.内存空间.磁盘 ...

  7. Linux下进程与线程的区别及查询方法

    在平时工作中,经常会听到应用程序的进程和线程的概念,那么它们两个之间究竟有什么关系或不同呢?一.深入理解进程和线程的区别 1)两者概念 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进 ...

  8. [Java]进程与线程的区别(转)

    线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间; (2)资源拥有: ...

  9. Java基础面试题(进程和线程的区别)

    进程和线程的区别 1.定义 进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程:进程的一个实体,是CPU调度和分派的基本单位,它是比进程更 ...

随机推荐

  1. SRTP讨论

    1.接下来任务如何分工? 2.接下来要完成哪些工作? 硬件上要完成哪些? 1)环境数据的采集(我) 2)对小车的控制(我) 3)路径规划(喻) 4)小车的避障(雷) 5)环境数据的处理融合(我) 6) ...

  2. oracle partition table 分区表详解

    Oracle partition table 分区表详解 分区表就是通过使用分区技术,将一张大表,拆分成多个表分区(独立的segment),从而提升数据访问的性能,以及日常的可维护性.分区表中,每个分 ...

  3. atom 为什么启动terminal是总是打开是用户目录?

    atom 为什么启动terminal是总是打开是用户目录?如下图: 原因也很简单,只怪自己懒,没查单词surpress是什么意思: surpress directory argument,是抑制目录参 ...

  4. 误删除innodb ibdata数据文件

    今天在群里看到有人说不熟悉innodb把ibdata(数据文件)和ib_logfile(事务日志)文件误删除了.不知道怎么解决.当时我也不知道怎么办.后来查阅相关资料.终找到解决方法.其实恢复也挺简单 ...

  5. magento 2.3安装测试数据

    前面我们一步步composer安装Magento2.3,但是没有数据的话各项设置不是很熟悉,所以最好还是安装一下测试数据.下面我们就跟ytkah一起填充数据.假设magento 2.3安装目录是/ww ...

  6. Wi-Fi 协议和数率?

    IEEE 802.11Wi-Fi 协议摘要 协议 频率 信号 最大数据速率 传统 802.11 2.4GHz FHSS 或 DSSS 2Mbps 802.11A 5GHz OFDM 54Mbps 80 ...

  7. Ubuntu中Redis的安装与使用

    安装 安装Redis服务器端 apt-get install redis-server 安装完成后,Redis服务器会自动启动,我们检查Redis服务器程序. 检查Redis服务器系统进程 ps -a ...

  8. element ui table 导出excel表格

    https://blog.csdn.net/u010427666/article/details/79208145 vue2.0 + element UI 中 el-table 数据导出Excel1. ...

  9. vue接口地址配一个全局的

    main.js加 if (process.env.NODE_ENV !== 'development') { Vue.prototype.URL_PREFIX = 'http://139.196.7. ...

  10. dfs模版

    dfs #include <stdio.h> #include <string.h> char Map[16][16]; int mv[16][16]; //mv[i][j] ...