多进程与多线程性能比较
进程与线程的区别 进程的通信方式 线程的通信方式

进程与线程的区别进程的通信方式线程的通信方式进程与线程的区别进程的通信方式线程的通信方式2011-03-15 01:04进程与线程的区别:通俗的解释一个系统运行着很多进程,可以比喻为一条马路上有很多马车不同的进程可以理解为不同的马车而同一辆马车可以有很多匹马来拉--这些马就是线程假设道路的宽度恰好可以通过一辆马车道路可以认为是临界资源那么马车成为分配资源的最小单位(进程)而同一个马车被很多匹马驱动(线程)--即最小的运行单位每辆马车马匹数=1所以马匹数=1的时候进程和线程没有严格界限,只存在一个概念上的区分度马匹数1的时候才可以严格区分进程和线程专业的解释:简而言之,一个程序至少有一个进程,一个进程至少有一个线程.线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。
每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。
但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。
但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。
这就是进程和线程的重要区别。
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行进程和线程的主要差别在于它们是不同的操作系统资源管理方式。
进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。
线程、进程的区别、优缺点

线程、进程的区别、优缺点进程的特点:每⼀个进程都有⾃⼰的独⽴的⼀块内存空间、⼀组资源系统。
其内部数据和状态都是完全独⽴的。
进程是操作系统进⾏资源分配的基本单位;线程是操作系统进⾏调度的基本单位。
同⼀进程下的线程不仅共享进程资源和内存,每个线程还可有⼀个属于它⾃⼰的内存空间——线程栈。
以下4⾏是我能理解的范围:多线程的优点:线程间切换快,共享数据,多核cpu利⽤率多线程的缺点:多线程同步、加锁控制较负责;多进程的优点:独⽴多进程的缺点:调度开销⼤====结==束=============结==束============结==束===============================================可以参考的:多线程的优点:⽆需跨进程边界;程序逻辑和控制⽅式简单;所有线程可以直接共享内存和变量等;线程⽅式消耗的总资源⽐进程⽅式好;多线程缺点:每个线程与主程序共⽤地址空间,受限于2GB地址空间;线程之间的同步和加锁控制⽐较⿇烦;⼀个线程的崩溃可能影响到整个程序的稳定性;到达⼀定的线程数程度后,即使再增加CPU也⽆法提⾼性能,例如Windows Server 2003,⼤约是1500个左右的线程数就快到极限了(线程堆栈设定为1M),如果设定线程堆栈为2M,还达不到1500个线程总数;线程能够提⾼的总性能有限,⽽且线程多了之后,线程本⾝的调度也是⼀个⿇烦事⼉,需要消耗较多的CPU多进程优点:每个进程互相独⽴,不影响主程序的稳定性,⼦进程崩溃没关系;通过增加CPU,就可以容易扩充性能;可以尽量减少线程加锁/解锁的影响,极⼤提⾼性能,就算是线程运⾏的模块算法效率低也没关系;每个⼦进程都有2GB地址空间和相关资源,总体能够达到的性能上限⾮常⼤多进程缺点:逻辑控制复杂,需要和主程序交互;需要跨进程边界,如果有⼤数据量传送,就不太好,适合⼩数据量传送、密集运算多进程调度开销⽐较⼤;如果多个线程要同时访问某个资源,怎么处理(java)?多线程的性能⼀定就由于单线程呢?不⼀定,要看具体的任务以及计算机的配置。
多线程和多进程的区别(C++)

多线程和多进程的区别(C++)很想写点关于多进程和多线程的东西,我确实很爱他们。
但是每每想动⼿写点关于他们的东西,却总是求全⼼理作祟,始终动不了⼿。
今天终于下了决⼼,写点东西,以后可以再修修补补也⽆妨。
⼀.为何需要多进程(或者多线程),为何需要并发?这个问题或许本⾝都不是个问题。
但是对于没有接触过多进程编程的朋友来说,他们确实⽆法感受到并发的魅⼒以及必要性。
我想,只要你不是整天都写那种int main()到底的代码的⼈,那么或多或少你会遇到代码响应不够⽤的情况,也应该有尝过并发编程的甜头。
就像⼀个快餐点的服务员,既要在前台接待客户点餐,⼜要接电话送外卖,没有分⾝术肯定会忙得你焦头烂额的。
幸运的是确实有这么⼀种技术,让你可以像孙悟空⼀样分⾝,灵魂出窍,乐哉乐哉地轻松应付⼀切状况,这就是多进程/线程技术。
并发技术,就是可以让你在同⼀时间同时执⾏多条任务的技术。
你的代码将不仅仅是从上到下,从左到右这样规规矩矩的⼀条线执⾏。
你可以⼀条线在main函数⾥跟你的客户交流,另⼀条线,你早就把你外卖送到了其他客户的⼿⾥。
所以,为何需要并发?因为我们需要更强⼤的功能,提供更多的服务,所以并发,必不可少。
⼆.多进程什么是进程。
最直观的就是⼀个个pid,官⽅的说法就:进程是程序在计算机上的⼀次执⾏活动。
说得简单点,下⾯这段代码执⾏的时候[cpp]1. int main()2.3. {4.5. printf(”pid is %d/n”,getpid() );6.7. return 0;8.9. }进⼊main函数,这就是⼀个进程,进程pid会打印出来,然后运⾏到return,该函数就退出,然后由于该函数是该进程的唯⼀的⼀次执⾏,所以return后,该进程也会退出。
看看多进程。
linux下创建⼦进程的调⽤是fork();[cpp]1. #include <unistd.h>2. #include <sys/types.h>3. #include <stdio.h>4.5.6.7. void print_exit()8. {9. printf("the exit pid:%d/n",getpid() );10. }11.12. main ()13. {14. pid_t pid;15. atexit( print_exit ); //注册该进程退出时的回调函数16. pid=fork();17. if (pid < 0)18. printf("error in fork!");19. else if (pid == 0)20. printf("i am the child process, my process id is %d/n",getpid());21. else22. {23. printf("i am the parent process, my process id is %d/n",getpid());24. sleep(2);25. wait();26. }27.28. }i am the child process, my process id is 15806the exit pid:15806i am the parent process, my process id is 15805the exit pid:15805这是gcc测试下的运⾏结果。
多线程知识点总结归纳

多线程知识点总结归纳多线程知识点总结归纳如下:1. 线程和进程的区别- 进程是程序的一个执行实例,每个进程都有自己的独立内存空间、代码和数据,相互之间不会直接共享资源。
线程是在进程内部运行的一段代码,多个线程可以共享同一个进程的资源。
2. 多线程的优势- 提高程序的并发性和响应性,能够更有效地利用 CPU 资源。
- 使得程序能够更轻松地实现并发处理和多任务处理。
- 能够通过多线程实现一些复杂任务,如网络编程、图形界面等。
3. 多线程的基本概念- 线程调度:操作系统通过调度算法决定哪个线程应当运行,哪个线程应当阻塞或唤醒。
- 线程同步:多个线程访问共享数据时需要进行同步操作,以避免数据竞争和死锁等问题。
- 线程通信:多个线程之间需要进行通信,以进行资源共享或协作完成任务。
4. 多线程的创建和启动- 使用线程类:在 Java 中,可以通过继承 Thread 类或实现 Runnable 接口来创建线程。
- 线程生命周期:线程的生命周期包括新建、就绪、运行、阻塞和死亡等状态。
5. 线程的安全性- 多线程程序需要考虑线程安全性,以避免数据竞争和死锁等问题。
- 常用的线程安全性方法包括加锁、使用线程安全的数据结构和对象等。
6. 线程的调度- 多线程程序的运行顺序由操作系统的调度算法决定,而且在不同的操作系统上可能有不同的调度策略。
- 线程的调度策略包括抢占式调度和协作式调度等。
7. 线程的优先级- 线程的优先级决定了它在被调度时的优先级,可以通过设置线程的优先级来影响它的调度顺序。
8. 线程的阻塞和唤醒- 线程在执行过程中可能会因为某些原因而阻塞,需要等待一定的条件满足后才能被唤醒继续执行。
- 一些常见的线程阻塞和唤醒操作包括等待、通知、等待超时等。
9. 线程同步的方法- 使用锁机制:在多线程程序中通常使用锁来保护共享资源,以避免数据竞争和执行顺序问题。
- 使用同步代码块:通过 synchronized 关键字或 ReentrantLock 类等来创建同步代码块,保护共享资源的访问。
c语言 多进程和多线程

进程是一个具有独立功能的程序关于某个数据集合的一次可以并发执行的运行活动,是处于活动状态的计算机程序。进程作为构成系统的基本细胞,不仅是系统内部独立运行的实体,而且是独立竞争资源的基本实体。
进程是资源管理的最小单位,线程是程序执行的最小单位。进程管理着资源(比如cpu、内存、文件等等),而将线程分配到某个cpu上执行。在操作系统设计上,从进程演化出线程,最主要的目的就是更好的支持多处理器系统和减小上下文切换开销。
进程的状态系统为了充分的利用资源,对进程区分了不同的状态.将进程分为新建,运行,阻塞,就绪和完成五个状态.
新建表示进程正在被创建,
运行是进程正在运行,
阻塞是进程正在等待某一个事件发生,
就绪是表示系统正在等待CPU来执行命令,
完成表示进程已经结束了系统正在回收资源.
由于UNIX系统是分时多用户系统, CPU按时间片分配给各个用户使用,而在实质上应该说CPU按时间片分配给各个进程使用,每个进程都有自己的运行环境以使得在CPU做进程切换时不会"忘记"该进程已计算了一半的"半成品”.以DOS的概念来说,进程的切换都 是一次"DOS中断"处理过程, 包括三个层次:
char *string;
说明:
本调用将参数string传递给一个命令解释器(一般为sh)执行,即string被解释为一条命令,由sh执行该命令.若参数string为一个空指针则为检查命令解释器是否存在.
该命令可以同命令行命令相同形式,但由于命令做为一个参数放在系统调用中,应注意编译时对特殊意义字符的处理.命令的查找是按PATH环境变量的定义的.命令所生成的后果一般不会对父进程造成影响.
}
pclose(fd);
2.
多线程与多进程的区别

多线程与多进程的区别(1)多线程多进程的区别维度多进程多线程总结数据共享、同步数据是分开的:共享复杂,需要⽤IPC;同步简单多线程共享进程数据:共享简单;同步复杂各有优势内存、CPU占⽤内存多,切换复杂,CPU利⽤率低占⽤内存少,切换简单,CPU利⽤率⾼线程占优创建销毁、切换创建销毁、切换复杂,速度慢创建销毁、切换简单,速度快线程占优编程调试编程简单,调试简单编程复杂,调试复杂进程占优可靠性进程间不会相互影响⼀个线程挂掉将导致整个进程挂掉进程占优分布式适应于多核、多机分布;如果⼀台机器不够,扩展到多台机器⽐较简单适应于多核分布进程占优然后我们来看下线程和进程间的⽐较⼦进程继承⽗进程的属性:⼦线程继承主线程的属性:实际⽤户ID,实际组ID,有效⽤户ID,有效组ID;附加组ID;进程组ID;会话ID;控制终端;设置⽤户ID标志和设置组ID标志;当前⼯作⽬录;根⽬录;⽂件模式创建屏蔽字(umask);信号屏蔽和安排;针对任⼀打开⽂件描述符的在执⾏时关闭(close-on-exec)标志;环境;连接的共享存储段;存储映射;资源限制;进程中的所有信息对该进程的所有线程都是共享的;可执⾏的程序⽂本;程序的全局内存;堆内存;栈;⽂件描述符;信号的处理是进程中所有线程共享的(注意:如果信号的默认处理是终⽌该进程那么即是把信号传给某个线程也⼀样会将进程杀掉);⽗⼦进程之间的区别:⼦线程特有的:fork的返回值(=0⼦进程);进程ID不同;两个进程具有不同的⽗进程ID;⼦进程的tms_utime,tms_stime,tms_cutime以及tms_ustime均被设置为0;不继承⽗进程设置的⽂件锁;⼦进程的未处理闹钟被清除;⼦进程的未处理信号集设置为空集;线程ID;⼀组寄存器值;栈;调度优先级和策略;信号屏蔽字;errno变量;线程私有数据;1)需要频繁创建销毁的优先⽤线程。
实例:web服务器。
来⼀个建⽴⼀个线程,断了就销毁线程。
Python的多线程(threading)与多进程(multiprocessing)

Python的多线程(threading)与多进程(multiprocessing)进程:程序的⼀次执⾏(程序载⼊内存,系统分配资源运⾏)。
每个进程有⾃⼰的内存空间,数据栈等,进程之间可以进⾏通讯,但是不能共享信息。
线程:所有的线程运⾏在同⼀个进程中,共享相同的运⾏环境。
每个独⽴的线程有⼀个程序⼊⼝,顺序执⾏序列和程序的出⼝。
线程的运⾏可以被强占,中断或者暂时被挂起(睡眠),让其他的线程运⾏。
⼀个进程中的各个线程共享同⼀⽚数据空间。
多线程import threadingdef thread_job():print "this is added thread,number is {}".format(threading.current_thread())def main():added_thread = threading.Thread(target = thread_job) #添加线程added_thread.start() #执⾏添加的线程print threading.active_count() #当前已被激活的线程的数⽬print threading.enumerate() #激活的是哪些线程print threading.current_thread() #正在运⾏的是哪些线程if __name__ == "__main__":main()this is added thread,number is <Thread(Thread-6, started 6244)>6[<HistorySavingThread(IPythonHistorySavingThread, started 7588)>, <ParentPollerWindows(Thread-3, started daemon 3364)>, <Heartbeat(Thread-5, started daemon 3056)>, <_MainThread(MainThread, started 1528)>, <Thread(Thread-6, started <_MainThread(MainThread, started 1528)>#join 功能等到线程执⾏完之后再回到主线程中去import threadingimport timedef T1_job():print "T1 start\n"for i in range(10):time.sleep(0.1)print "T1 finish"def T2_job():print 'T2 start'print 'T2 finish'def main():thread1 = threading.Thread(target = T1_job) #添加线程thread2 = threading.Thread(target = T2_job)thread1.start() #执⾏添加的线程thread2.start()thread1.join()thread2.join()print 'all done\n'if __name__ == "__main__":main()T1 startT2 startT2 finishT1 finishall done#queue 多线程各个线程的运算的值放到⼀个队列中,到主线程的时候再拿出来,以此来代替#return的功能,因为在线程是不能返回⼀个值的import timeimport threadingfrom Queue import Queuedef job(l,q):q.put([i**2 for i in l])def multithreading(data):q = Queue()threads = []for i in xrange(4):t = threading.Thread(target = job,args = (data[i],q))t.start()threads.append(t)for thread in threads:thread.join()results = []for _ in range(4):results.append(q.get())print resultsif __name__ == "__main__":data = [[1,2,3],[4,5,6],[3,4,3],[5,5,5]]multithreading(data)[[1, 4, 9], [16, 25, 36], [9, 16, 9], [25, 25, 25]]#多线程的锁import threadingimport timedef T1_job():global A,locklock.acquire()for i in xrange(10):A += 1print 'T1_job',Alock.release()def T2_job():global A,locklock.acquire()for i in xrange(10):A += 10print 'T2_job',Aif __name__ == "__main__":lock = threading.Lock()A = 0 #全局变量thread1 = threading.Thread(target = T1_job) #添加线程thread2 = threading.Thread(target = T2_job)thread1.start() #执⾏添加的线程thread2.start()thread1.join()thread2.join() 全局解释器锁GIL(Global Interpreter Lock)GIL并不是Python的特性,他是CPython引⼊的概念,是⼀个全局排他锁。
线程、进程、多线程、多进程和多任务之间的区别与联系

线程、进程、多线程、多进程和多任务之间的区别与联系可能学习操作系统开发的读者都听说过这些专业名词,但又多少人理解了?首先,从定义开始,先看一下教科书上进程和线程定义:进程:资源分配的最小单位。
线程:程序执行的最小单位。
1进程进程是程序执行时的一个实例,即它是程序已经执行到课中程度的数据结构的汇集。
从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。
举例说明进程:想象一位有一手好厨艺的计算机科学家正在为他的女儿烘制生日蛋糕,他有做生日蛋糕的食谱,厨房里有所需的原料:面粉、鸡蛋、糖、香草汁等。
在这个比喻中,做蛋糕的食谱就是程序(即用适当形式描述的算法)计算机科学家就是处理器(CPU),而做蛋糕的各种原料就是输入数据。
进程就是厨师阅读食谱、取来各种原料以及烘制蛋糕等一系列动作的总和。
现在假设计算机科学家的儿子哭着跑了进来,说他的头被一只蜜蜂蛰了。
计算机科学家就记录下他照着食谱做到哪儿了(保存进程的当前状态),然后拿出一本急救手册,按照其中的指示处理蛰伤。
这里,我们看到处理机制是从一个进程(做蛋糕)切换到另一个高优先级的进程(实施医疗救治),每个进程拥有各自的程序(食谱和急救手册)。
当蜜蜂蛰伤处理完之后,这位计算机科学家又回来做蛋糕,从他离开时的那一步继续做下去。
2线程线程是CPU调度的最小单位(程序执行流的最小单元),它被包含在进程之中,是进程中的实际运作单元。
一条线程是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
一个标准的线程有线程ID、当前指令指针(PC),寄存器集合和堆栈组成。
另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单元,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。
一个线程可以创建和撤销另一个线程,同一进程中的多个线程之间可以并发执行。
由于线程之间的相互制约,致使线程在运行中呈现处间断性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.多进程与多线程并发速度的实验对比
在多进程与多线程并发运行速度的问题上,一般认为线程的创建销毁速度快,进程的创建销毁速度慢,多线程的速度要优于多进程。
为了得到明确结果,在192.168.1.141的主机上使用了thread.c和fork.c两个程序进行测试。
(测试程序基于论文《Linux系统下多线程与多进程性能分析》作者“周丽焦程波兰巨龙”)
fork.c
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#define P_NUMBER 127
#define COUNT 50
#define P_NUMBER 127 /* 并发进程数量*/
#define COUNT 50 /* 每进程打印字符串次数*/
char *s = "hello linux\0";
int main(void)
{
int i = 0, j = 0;
logFile = fopen(TEST_LOGFILE, "a+");
for (i = 0;i < P_NUMBER; i ++){
if (fork() == 0){
for (j = 0;j < COUNT; j ++){
printf("[%d]%s\n", j, s);
fprintf(logFile, "[%d]%s\n", j, s);
}
exit(0);
}
}
for (i = 0;i < P_NUMBER; i ++){
wait(0);
}
}
thread.c
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define P_NUMBER 127 /* 并发线程数量*/
#define COUNT 50 /* 每线程打印字符串次数*/
#define Test_Log "logFile.log"
FILE *logFile = NULL;
char *s = "hello linux\0";
print_hello_linux() /* 线程执行的函数*/
{
int i = 0;
for(i = 0; i < COUNT; i ++)
{
printf("[%d]%s\n", i, s); /* 向控制台输出*/
fprintf(logFile, "[%d]%s\n", i, s); /* 向日志文件输出*/
}
pthread_exit(0); /* 线程结束*/
}
int main()
{
int i = 0;
pthread_t pid[P_NUMBER]; /* 线程数组*/
logFile = fopen(Test_Log, "a+"); /* 打开日志文件*/
for (i = 0; i < P_NUMBER; i ++)
pthread_create(&pid[i], NULL, (void *)print_hello_linux, NULL); /* 创建>
线程*/
for (i = 0; i < P_NUMBER; i ++)
pthread_join(pid[i], NULL); /* 回收线程*/
printf("over\n");
return 0;
}
在测试过程中,通过改变P_NUMBER和COUNT两个宏定义值,调整程序的执行。
测试结果如下表所示。
(实验数据均为经过5次运行得到的平均数据)
从实验结果中可以看出,在数据量较小且不进行数据共享时,多进程程序和多线程程序在并发处理上速度并没有明显的差别。
当数据量变大时,多进程有变慢的趋势。
在系统中,会有进程数量和线程数量限制,进程数量可通过“ulimit -a”命令查询,192.168.1.141上的默认进程数限制为1024个。
线程数量主要受虚拟内存和栈内存大小限制,192.168.1.141上默认线程数限制为1019个。
进程最大数量和线程最大数量均可修改。
2.多进程与多线程的性能对比
在不同的性能指标上,多进程与多线程有不同的优缺点,主要对比如下表所示。
3.结论
根据上一节的性能对比,可以得到以下结论。
i.需要频繁的创建与销毁,优先使用线程。
比如说在web应用中,需要频
繁的创建与销毁连接,这时使用多线程为佳。
ii.后台需要大量的计算,优先使用线程。
一般需要保证用户界面响应速度的系统都需要使用多线程,将后台运算和用户界面分成两个线程。
iii.需要保证系统的稳定性,使用进程。
对于需要长时间保持运行的程序,尽量使用进程。
iv.可能扩展到多机分布的优先使用进程,多核分布优先使用线程。
多线程对比多进程,优势在于多核CPU利用率高,在多核分布时优先使用线程。
当需要扩展到其它机器时,使用进程。
v.功能上有很强的相关性,使用线程;功能上相关性不高,使用进程。
比如在服务器上需要完成如下任务:消息收发、消息处理。
“消息收发”和“消息处理”就是弱相关的任务,而“消息处理”里面可能又分为“消息解码”、“业务处理”,这两个任务相对来说相关性就要强多了。
因此“消息收发”和“消息处理”可以分进程设计,“消息解码”、“业务处理”可以分线程设计。