操作系统

操作系统

如何不借助任何第三方软件快速激活Windows10?

回复

工具软件zkbhj 发起了问题 • 1 人关注 • 0 个回复 • 2053 次浏览 • 2020-05-20 14:43 • 来自相关话题

#2020学习打卡##C程序设计语言# 32位的系统,是怎么操作运算64位的数据的?

回复

C语言zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 1368 次浏览 • 2020-04-08 12:49 • 来自相关话题

#2020学习打卡##C程序设计语言# Long类型在windows和Mac(类unix)系统下的差异分析

C语言zkbhj 发表了文章 • 0 个评论 • 670 次浏览 • 2020-04-08 11:36 • 来自相关话题

在今天的课堂任务中,相同的程序代码,在windows和Mac os两个平台下,编译执行之后的结果竟然不太一样,有点儿“奇怪”,想知道原因为何?所以进行了一番研究梳理!
 
首先看下代码源码:很简单,要求就是通过标准文件中定义的常量 和 计算 两种方式来显示各数据类型的实际取值范围。#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %ld ~ %ld\n",LONG_MIN , LONG_MAX);
printf("unSigned long: %d ~ %lu\n",0 , ULONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %ld ~ %ld\n",-(long)((unsigned long) ~0 >> 1) - 1, (long)((unsigned long) ~0 >> 1));
printf("unSigned long: %d ~ %lu\n",0 ,(unsigned long) ~0);

//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}#操作系统的情况
Windows 10 64位系统
Mac OS 64位系统




 
可以看到,char、short、int这三个类型的数据长度,在两个平台下的长度是一致的,但是long类型就不太一样了,明显mac上的取值范围更大,而且大很多~ 为什么呢?
 
我们都知道,类型的取值范围是多少,取决于其所占用的位数,那么两个平台,针对long类型,显然分配的位数是不同的。通过sizeof(对这个详细了解再总结吧),总之它是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。所以,在程序中加入了下面的代码,查看下两个系统中long分别分配的内存字节数,就可以知道对应的位数了。
 //查看类型占用字节数
long a;
printf("%ld", sizeof a);果然,在Windows下,输出结果是4,在mac下输出结果是8。换算成位数,也就是windows下是32位,mac下是64位。这就解释了为啥两个系统下的long类型取值范围为啥不相同了。
 
但是另外一个问题来了:为啥同样是64位系统,window下long就是32位,而Mac下是64位呢?经过查询资料,才发现其中的门道。
 
在Unix世界中,针对64位平台的整数和指针的大小有一些可能的安排。其中最常用的两个是ILP64(实际上,这只是其中的一小部分例子,Cray就是这样)和LP64(几乎所有其他的)。首字母来自'int,long,指针是64位'和'long,指针是64位'。
 Type ILP64 LP64 LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64ILP64系统因LP64而被放弃(也就是说,几乎所有后来的进入者都使用LP64,这是基于Aspen小组的建议;只有具有64位操作悠久遗产的系统使用不同的方案)。所有现代的64位Unix系统都使用LP64。MacOS X和Linux都是现代64位系统。

Microsoft使用不同的方案转换为64位:LLP64('long long,指针为64位')。这意味着32位软件可以在不改变的情况下重新编译。它具有与其他人不同的缺点,还需要对代码进行修改以利用64位容量。总是需要修改; 它只是与Unix平台上需要的版本不同的修订版本。 
这下可以解释了,为什么windows下的long类型是32位的,因为Microsoft针对64位系统,采用的是LLP64位的方案。在这方案里,long类型是32位,longlong类型才是64位。在windows的官方说明文档中,也可以查到相应的类型释义:





 
那么,我们把程序改一改,是不是就可以输出相同的结果了呢?答案,不置可否!修改后的程序如下:#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %lld ~ %lld\n",LONG_LONG_MIN , LONG_LONG_MAX);
printf("unSigned long: %d ~ %llu\n",0 , ULLONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %lld ~ %lld\n",-(long long)((unsigned long long) ~0 >> 1) - 1, (long long)((unsigned long long) ~0 >> 1));
printf("unSigned long: %d ~ %llu\n",0 ,(unsigned long long) ~0);


//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}主要看long类型,我们替换成了long long,它对应的头文件常量是:LONG_LONG_MIN、LONG_LONG_MAX和ULLONG_MAX。当然,输出这个长度的数据,要使用 %lld 和 %llu。否则数据输出会变小。
 
题外话:
 
首先要说的是,和Java等语言不同,C/C++本身并没有规定各数据类型的位数,只是限定了一个大小关系,也就是规定从所占的bit数来说,short <= int <= long <= long long。至于具体哪种类型占用多少位,是由你所用的开发平台的编译器决定的。在现在的PC上一个通常的标准是,int和long同为32位,long long为64位。但是如果换到其它平台(如ARM)上,这个数字可能会有不同,类型所占的大小可以用sizeof()运算符查看。

long long是C99标准中新引进的数据类型,在古老的VC6.0中并没有这个类型,所以在VC6.0中用”long long”会发生编译错误。为了表示64位整数,VC6里采用的是微软自己搞出来的一个数据类型,叫做__int64,所以如果你是在VC6.0下编译的话,应该用__int64定义64位整型。新版的Visual Studio已经支持long long了。GCC是支持long long的,我们在win系统中使用的其它IDE如Dev-Cpp, Code::Blocks等等大多是采用的MinGW编译环境,它是与GCC兼容的,所以也支持long long(另外为了与MS兼容,也支持__int64)。如果是在纯的linux下,就只能使用long long了。

关于使用printf的输入输出,这里就有一个更囧的情况。实际上只要记住,主要的区分在于操作系统:如果在win系统下,那么无论什么编译器,一律用%I64d;如果在linux系统,一律用%lld。这是因为MS提供的msvcrt.dll库里使用的就是%I64d的方式,尽管Dev-Cpp等在语法上支持标准,但也不得不使用MS提供的dll库来完成IO,所以就造成了这种情况。

参考文档:
https://docs.microsoft.com/zh-cn/windows/win32/winprog/windows-data-types
https://cloud.tencent.com/developer/ask/62686
https://blog.csdn.net/qq_31736627/article/details/52912691
  查看全部
在今天的课堂任务中,相同的程序代码,在windows和Mac os两个平台下,编译执行之后的结果竟然不太一样,有点儿“奇怪”,想知道原因为何?所以进行了一番研究梳理!
 
首先看下代码源码:很简单,要求就是通过标准文件中定义的常量 和 计算 两种方式来显示各数据类型的实际取值范围。
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %ld ~ %ld\n",LONG_MIN , LONG_MAX);
printf("unSigned long: %d ~ %lu\n",0 , ULONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %ld ~ %ld\n",-(long)((unsigned long) ~0 >> 1) - 1, (long)((unsigned long) ~0 >> 1));
printf("unSigned long: %d ~ %lu\n",0 ,(unsigned long) ~0);

//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}
#操作系统的情况
Windows 10 64位系统
Mac OS 64位系统

QQ截图20200408111541.jpg

 
可以看到,char、short、int这三个类型的数据长度,在两个平台下的长度是一致的,但是long类型就不太一样了,明显mac上的取值范围更大,而且大很多~ 为什么呢?
 
我们都知道,类型的取值范围是多少,取决于其所占用的位数,那么两个平台,针对long类型,显然分配的位数是不同的。通过sizeof(对这个详细了解再总结吧),总之它是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。所以,在程序中加入了下面的代码,查看下两个系统中long分别分配的内存字节数,就可以知道对应的位数了。
 
//查看类型占用字节数
long a;
printf("%ld", sizeof a);
果然,在Windows下,输出结果是4,在mac下输出结果是8。换算成位数,也就是windows下是32位,mac下是64位。这就解释了为啥两个系统下的long类型取值范围为啥不相同了。
 
但是另外一个问题来了:为啥同样是64位系统,window下long就是32位,而Mac下是64位呢?经过查询资料,才发现其中的门道。
 
在Unix世界中,针对64位平台的整数和指针的大小有一些可能的安排。其中最常用的两个是ILP64(实际上,这只是其中的一小部分例子,Cray就是这样)和LP64(几乎所有其他的)。首字母来自'int,long,指针是64位'和'long,指针是64位'。
 
Type           ILP64   LP64   LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64
ILP64系统因LP64而被放弃(也就是说,几乎所有后来的进入者都使用LP64,这是基于Aspen小组的建议;只有具有64位操作悠久遗产的系统使用不同的方案)。所有现代的64位Unix系统都使用LP64。MacOS X和Linux都是现代64位系统。

Microsoft使用不同的方案转换为64位:LLP64('long long,指针为64位')。这意味着32位软件可以在不改变的情况下重新编译。它具有与其他人不同的缺点,还需要对代码进行修改以利用64位容量。总是需要修改; 它只是与Unix平台上需要的版本不同的修订版本。 
这下可以解释了,为什么windows下的long类型是32位的,因为Microsoft针对64位系统,采用的是LLP64位的方案。在这方案里,long类型是32位,longlong类型才是64位。在windows的官方说明文档中,也可以查到相应的类型释义:

QQ截图20200408113111.jpg

 
那么,我们把程序改一改,是不是就可以输出相同的结果了呢?答案,不置可否!修改后的程序如下:
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %lld ~ %lld\n",LONG_LONG_MIN , LONG_LONG_MAX);
printf("unSigned long: %d ~ %llu\n",0 , ULLONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %lld ~ %lld\n",-(long long)((unsigned long long) ~0 >> 1) - 1, (long long)((unsigned long long) ~0 >> 1));
printf("unSigned long: %d ~ %llu\n",0 ,(unsigned long long) ~0);


//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}
主要看long类型,我们替换成了long long,它对应的头文件常量是:LONG_LONG_MIN、LONG_LONG_MAX和ULLONG_MAX。当然,输出这个长度的数据,要使用 %lld 和 %llu。否则数据输出会变小。
 
题外话:
 
首先要说的是,和Java等语言不同,C/C++本身并没有规定各数据类型的位数,只是限定了一个大小关系,也就是规定从所占的bit数来说,short <= int <= long <= long long。至于具体哪种类型占用多少位,是由你所用的开发平台的编译器决定的。在现在的PC上一个通常的标准是,int和long同为32位,long long为64位。但是如果换到其它平台(如ARM)上,这个数字可能会有不同,类型所占的大小可以用sizeof()运算符查看。

long long是C99标准中新引进的数据类型,在古老的VC6.0中并没有这个类型,所以在VC6.0中用”long long”会发生编译错误。为了表示64位整数,VC6里采用的是微软自己搞出来的一个数据类型,叫做__int64,所以如果你是在VC6.0下编译的话,应该用__int64定义64位整型。新版的Visual Studio已经支持long long了。GCC是支持long long的,我们在win系统中使用的其它IDE如Dev-Cpp, Code::Blocks等等大多是采用的MinGW编译环境,它是与GCC兼容的,所以也支持long long(另外为了与MS兼容,也支持__int64)。如果是在纯的linux下,就只能使用long long了

关于使用printf的输入输出,这里就有一个更囧的情况。实际上只要记住,主要的区分在于操作系统:如果在win系统下,那么无论什么编译器,一律用%I64d;如果在linux系统,一律用%lld。这是因为MS提供的msvcrt.dll库里使用的就是%I64d的方式,尽管Dev-Cpp等在语法上支持标准,但也不得不使用MS提供的dll库来完成IO,所以就造成了这种情况。

参考文档:
https://docs.microsoft.com/zh-cn/windows/win32/winprog/windows-data-types
https://cloud.tencent.com/developer/ask/62686
https://blog.csdn.net/qq_31736627/article/details/52912691
 

如何在windows当前目录下打开cmd命令窗口?

回复

工具软件zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 2874 次浏览 • 2017-06-12 13:09 • 来自相关话题

Windows下面怎么创建和删除软连接?

回复

工具软件zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 2678 次浏览 • 2017-06-11 23:00 • 来自相关话题

进程和线程的区别和联系

专业名词zkbhj 发表了文章 • 0 个评论 • 966 次浏览 • 2016-12-27 17:51 • 来自相关话题

1.定义

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

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

2.关系
 
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

3.区别
 
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

2) 线程的划分尺度小于进程,使得多线程程序的并发性高。

3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。

 这就是进程和线程的重要区别。

4.优缺点
 
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

5.举例记忆
 
计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。一个车间里,可以有很多工人。他们协同完成一个任务。线程就好比车间里的工人。一个进程可以包括多个线程。车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫"互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做"信号量"(Semaphore),用来保证多个线程不会互相冲突。

不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。
 
操作系统的设计,因此可以归结为三点:

(1)以多进程形式,允许多个任务同时运行;

(2)以多线程形式,允许单个任务分成不同的部分运行;

(3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。 查看全部
1.定义

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

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

2.关系
 
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

3.区别
 
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。


1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

2) 线程的划分尺度小于进程,使得多线程程序的并发性高。

3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。


 这就是进程和线程的重要区别。

4.优缺点
 
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

5.举例记忆
 

计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。一个车间里,可以有很多工人。他们协同完成一个任务。线程就好比车间里的工人。一个进程可以包括多个线程。车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫"互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做"信号量"(Semaphore),用来保证多个线程不会互相冲突。

不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。
 
操作系统的设计,因此可以归结为三点:


(1)以多进程形式,允许多个任务同时运行;

(2)以多线程形式,允许单个任务分成不同的部分运行;

(3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。


如何不借助任何第三方软件快速激活Windows10?

回复

工具软件zkbhj 发起了问题 • 1 人关注 • 0 个回复 • 2053 次浏览 • 2020-05-20 14:43 • 来自相关话题

#2020学习打卡##C程序设计语言# 32位的系统,是怎么操作运算64位的数据的?

回复

C语言zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 1368 次浏览 • 2020-04-08 12:49 • 来自相关话题

如何在windows当前目录下打开cmd命令窗口?

回复

工具软件zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 2874 次浏览 • 2017-06-12 13:09 • 来自相关话题

Windows下面怎么创建和删除软连接?

回复

工具软件zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 2678 次浏览 • 2017-06-11 23:00 • 来自相关话题

#2020学习打卡##C程序设计语言# Long类型在windows和Mac(类unix)系统下的差异分析

C语言zkbhj 发表了文章 • 0 个评论 • 670 次浏览 • 2020-04-08 11:36 • 来自相关话题

在今天的课堂任务中,相同的程序代码,在windows和Mac os两个平台下,编译执行之后的结果竟然不太一样,有点儿“奇怪”,想知道原因为何?所以进行了一番研究梳理!
 
首先看下代码源码:很简单,要求就是通过标准文件中定义的常量 和 计算 两种方式来显示各数据类型的实际取值范围。#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %ld ~ %ld\n",LONG_MIN , LONG_MAX);
printf("unSigned long: %d ~ %lu\n",0 , ULONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %ld ~ %ld\n",-(long)((unsigned long) ~0 >> 1) - 1, (long)((unsigned long) ~0 >> 1));
printf("unSigned long: %d ~ %lu\n",0 ,(unsigned long) ~0);

//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}#操作系统的情况
Windows 10 64位系统
Mac OS 64位系统




 
可以看到,char、short、int这三个类型的数据长度,在两个平台下的长度是一致的,但是long类型就不太一样了,明显mac上的取值范围更大,而且大很多~ 为什么呢?
 
我们都知道,类型的取值范围是多少,取决于其所占用的位数,那么两个平台,针对long类型,显然分配的位数是不同的。通过sizeof(对这个详细了解再总结吧),总之它是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。所以,在程序中加入了下面的代码,查看下两个系统中long分别分配的内存字节数,就可以知道对应的位数了。
 //查看类型占用字节数
long a;
printf("%ld", sizeof a);果然,在Windows下,输出结果是4,在mac下输出结果是8。换算成位数,也就是windows下是32位,mac下是64位。这就解释了为啥两个系统下的long类型取值范围为啥不相同了。
 
但是另外一个问题来了:为啥同样是64位系统,window下long就是32位,而Mac下是64位呢?经过查询资料,才发现其中的门道。
 
在Unix世界中,针对64位平台的整数和指针的大小有一些可能的安排。其中最常用的两个是ILP64(实际上,这只是其中的一小部分例子,Cray就是这样)和LP64(几乎所有其他的)。首字母来自'int,long,指针是64位'和'long,指针是64位'。
 Type ILP64 LP64 LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64ILP64系统因LP64而被放弃(也就是说,几乎所有后来的进入者都使用LP64,这是基于Aspen小组的建议;只有具有64位操作悠久遗产的系统使用不同的方案)。所有现代的64位Unix系统都使用LP64。MacOS X和Linux都是现代64位系统。

Microsoft使用不同的方案转换为64位:LLP64('long long,指针为64位')。这意味着32位软件可以在不改变的情况下重新编译。它具有与其他人不同的缺点,还需要对代码进行修改以利用64位容量。总是需要修改; 它只是与Unix平台上需要的版本不同的修订版本。 
这下可以解释了,为什么windows下的long类型是32位的,因为Microsoft针对64位系统,采用的是LLP64位的方案。在这方案里,long类型是32位,longlong类型才是64位。在windows的官方说明文档中,也可以查到相应的类型释义:





 
那么,我们把程序改一改,是不是就可以输出相同的结果了呢?答案,不置可否!修改后的程序如下:#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %lld ~ %lld\n",LONG_LONG_MIN , LONG_LONG_MAX);
printf("unSigned long: %d ~ %llu\n",0 , ULLONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %lld ~ %lld\n",-(long long)((unsigned long long) ~0 >> 1) - 1, (long long)((unsigned long long) ~0 >> 1));
printf("unSigned long: %d ~ %llu\n",0 ,(unsigned long long) ~0);


//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}主要看long类型,我们替换成了long long,它对应的头文件常量是:LONG_LONG_MIN、LONG_LONG_MAX和ULLONG_MAX。当然,输出这个长度的数据,要使用 %lld 和 %llu。否则数据输出会变小。
 
题外话:
 
首先要说的是,和Java等语言不同,C/C++本身并没有规定各数据类型的位数,只是限定了一个大小关系,也就是规定从所占的bit数来说,short <= int <= long <= long long。至于具体哪种类型占用多少位,是由你所用的开发平台的编译器决定的。在现在的PC上一个通常的标准是,int和long同为32位,long long为64位。但是如果换到其它平台(如ARM)上,这个数字可能会有不同,类型所占的大小可以用sizeof()运算符查看。

long long是C99标准中新引进的数据类型,在古老的VC6.0中并没有这个类型,所以在VC6.0中用”long long”会发生编译错误。为了表示64位整数,VC6里采用的是微软自己搞出来的一个数据类型,叫做__int64,所以如果你是在VC6.0下编译的话,应该用__int64定义64位整型。新版的Visual Studio已经支持long long了。GCC是支持long long的,我们在win系统中使用的其它IDE如Dev-Cpp, Code::Blocks等等大多是采用的MinGW编译环境,它是与GCC兼容的,所以也支持long long(另外为了与MS兼容,也支持__int64)。如果是在纯的linux下,就只能使用long long了。

关于使用printf的输入输出,这里就有一个更囧的情况。实际上只要记住,主要的区分在于操作系统:如果在win系统下,那么无论什么编译器,一律用%I64d;如果在linux系统,一律用%lld。这是因为MS提供的msvcrt.dll库里使用的就是%I64d的方式,尽管Dev-Cpp等在语法上支持标准,但也不得不使用MS提供的dll库来完成IO,所以就造成了这种情况。

参考文档:
https://docs.microsoft.com/zh-cn/windows/win32/winprog/windows-data-types
https://cloud.tencent.com/developer/ask/62686
https://blog.csdn.net/qq_31736627/article/details/52912691
  查看全部
在今天的课堂任务中,相同的程序代码,在windows和Mac os两个平台下,编译执行之后的结果竟然不太一样,有点儿“奇怪”,想知道原因为何?所以进行了一番研究梳理!
 
首先看下代码源码:很简单,要求就是通过标准文件中定义的常量 和 计算 两种方式来显示各数据类型的实际取值范围。
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %ld ~ %ld\n",LONG_MIN , LONG_MAX);
printf("unSigned long: %d ~ %lu\n",0 , ULONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %ld ~ %ld\n",-(long)((unsigned long) ~0 >> 1) - 1, (long)((unsigned long) ~0 >> 1));
printf("unSigned long: %d ~ %lu\n",0 ,(unsigned long) ~0);

//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}
#操作系统的情况
Windows 10 64位系统
Mac OS 64位系统

QQ截图20200408111541.jpg

 
可以看到,char、short、int这三个类型的数据长度,在两个平台下的长度是一致的,但是long类型就不太一样了,明显mac上的取值范围更大,而且大很多~ 为什么呢?
 
我们都知道,类型的取值范围是多少,取决于其所占用的位数,那么两个平台,针对long类型,显然分配的位数是不同的。通过sizeof(对这个详细了解再总结吧),总之它是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。所以,在程序中加入了下面的代码,查看下两个系统中long分别分配的内存字节数,就可以知道对应的位数了。
 
//查看类型占用字节数
long a;
printf("%ld", sizeof a);
果然,在Windows下,输出结果是4,在mac下输出结果是8。换算成位数,也就是windows下是32位,mac下是64位。这就解释了为啥两个系统下的long类型取值范围为啥不相同了。
 
但是另外一个问题来了:为啥同样是64位系统,window下long就是32位,而Mac下是64位呢?经过查询资料,才发现其中的门道。
 
在Unix世界中,针对64位平台的整数和指针的大小有一些可能的安排。其中最常用的两个是ILP64(实际上,这只是其中的一小部分例子,Cray就是这样)和LP64(几乎所有其他的)。首字母来自'int,long,指针是64位'和'long,指针是64位'。
 
Type           ILP64   LP64   LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64
ILP64系统因LP64而被放弃(也就是说,几乎所有后来的进入者都使用LP64,这是基于Aspen小组的建议;只有具有64位操作悠久遗产的系统使用不同的方案)。所有现代的64位Unix系统都使用LP64。MacOS X和Linux都是现代64位系统。

Microsoft使用不同的方案转换为64位:LLP64('long long,指针为64位')。这意味着32位软件可以在不改变的情况下重新编译。它具有与其他人不同的缺点,还需要对代码进行修改以利用64位容量。总是需要修改; 它只是与Unix平台上需要的版本不同的修订版本。 
这下可以解释了,为什么windows下的long类型是32位的,因为Microsoft针对64位系统,采用的是LLP64位的方案。在这方案里,long类型是32位,longlong类型才是64位。在windows的官方说明文档中,也可以查到相应的类型释义:

QQ截图20200408113111.jpg

 
那么,我们把程序改一改,是不是就可以输出相同的结果了呢?答案,不置可否!修改后的程序如下:
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{

//从标准头文件中输出
printf("The values from standard file:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n",SCHAR_MIN , SCHAR_MAX);
printf("unSigned char: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed short: %d ~ %d\n",SHRT_MIN, SHRT_MAX);
printf("unSigned short: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed int: %d ~ %d\n",INT_MIN, INT_MAX);
printf("unSigned int: %d ~ %u\n",0 , UCHAR_MAX);
printf("signed long: %lld ~ %lld\n",LONG_LONG_MIN , LONG_LONG_MAX);
printf("unSigned long: %d ~ %llu\n",0 , ULLONG_MAX);
printf("------------------------------\n");

//直接计算
printf("The values from calculate:\n");
printf("------------------------------\n");
printf("signed char: %d ~ %d\n", -(char)((unsigned char) ~0 >> 1) - 1, (char)((unsigned char) ~0 >> 1));
printf("unSigned char: %d ~ %u\n",0 , (unsigned char) ~0);
printf("signed short: %d ~ %d\n",-(short)((unsigned short) ~0 >> 1) - 1, (short)((unsigned short) ~0 >> 1));
printf("unSigned short: %d ~ %u\n",0 , (unsigned short) ~0);
printf("signed int: %d ~ %d\n",-(int)((unsigned int) ~0 >> 1) - 1, (int)((unsigned int) ~0 >> 1));
printf("unSigned int: %d ~ %u\n",0 ,(unsigned int) ~0);
printf("signed long: %lld ~ %lld\n",-(long long)((unsigned long long) ~0 >> 1) - 1, (long long)((unsigned long long) ~0 >> 1));
printf("unSigned long: %d ~ %llu\n",0 ,(unsigned long long) ~0);


//查看类型占用字节数
long long a;
printf("%ld", sizeof a);
return 0;

}
主要看long类型,我们替换成了long long,它对应的头文件常量是:LONG_LONG_MIN、LONG_LONG_MAX和ULLONG_MAX。当然,输出这个长度的数据,要使用 %lld 和 %llu。否则数据输出会变小。
 
题外话:
 
首先要说的是,和Java等语言不同,C/C++本身并没有规定各数据类型的位数,只是限定了一个大小关系,也就是规定从所占的bit数来说,short <= int <= long <= long long。至于具体哪种类型占用多少位,是由你所用的开发平台的编译器决定的。在现在的PC上一个通常的标准是,int和long同为32位,long long为64位。但是如果换到其它平台(如ARM)上,这个数字可能会有不同,类型所占的大小可以用sizeof()运算符查看。

long long是C99标准中新引进的数据类型,在古老的VC6.0中并没有这个类型,所以在VC6.0中用”long long”会发生编译错误。为了表示64位整数,VC6里采用的是微软自己搞出来的一个数据类型,叫做__int64,所以如果你是在VC6.0下编译的话,应该用__int64定义64位整型。新版的Visual Studio已经支持long long了。GCC是支持long long的,我们在win系统中使用的其它IDE如Dev-Cpp, Code::Blocks等等大多是采用的MinGW编译环境,它是与GCC兼容的,所以也支持long long(另外为了与MS兼容,也支持__int64)。如果是在纯的linux下,就只能使用long long了

关于使用printf的输入输出,这里就有一个更囧的情况。实际上只要记住,主要的区分在于操作系统:如果在win系统下,那么无论什么编译器,一律用%I64d;如果在linux系统,一律用%lld。这是因为MS提供的msvcrt.dll库里使用的就是%I64d的方式,尽管Dev-Cpp等在语法上支持标准,但也不得不使用MS提供的dll库来完成IO,所以就造成了这种情况。

参考文档:
https://docs.microsoft.com/zh-cn/windows/win32/winprog/windows-data-types
https://cloud.tencent.com/developer/ask/62686
https://blog.csdn.net/qq_31736627/article/details/52912691
 

进程和线程的区别和联系

专业名词zkbhj 发表了文章 • 0 个评论 • 966 次浏览 • 2016-12-27 17:51 • 来自相关话题

1.定义

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

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

2.关系
 
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

3.区别
 
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

2) 线程的划分尺度小于进程,使得多线程程序的并发性高。

3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。

 这就是进程和线程的重要区别。

4.优缺点
 
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

5.举例记忆
 
计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。一个车间里,可以有很多工人。他们协同完成一个任务。线程就好比车间里的工人。一个进程可以包括多个线程。车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫"互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做"信号量"(Semaphore),用来保证多个线程不会互相冲突。

不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。
 
操作系统的设计,因此可以归结为三点:

(1)以多进程形式,允许多个任务同时运行;

(2)以多线程形式,允许单个任务分成不同的部分运行;

(3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。 查看全部
1.定义

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

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

2.关系
 
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

3.区别
 
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。


1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

2) 线程的划分尺度小于进程,使得多线程程序的并发性高。

3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。


 这就是进程和线程的重要区别。

4.优缺点
 
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

5.举例记忆
 

计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。一个车间里,可以有很多工人。他们协同完成一个任务。线程就好比车间里的工人。一个进程可以包括多个线程。车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫"互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做"信号量"(Semaphore),用来保证多个线程不会互相冲突。

不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。
 
操作系统的设计,因此可以归结为三点:


(1)以多进程形式,允许多个任务同时运行;

(2)以多线程形式,允许单个任务分成不同的部分运行;

(3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。