
任一按键消息 -> 被安装低级键盘钩子线程截获(在函数中处理)-> 根据键盘消息目标分到各进程消息队列 -> 进程getmessage对其处理。当然了,线程是不存在交叉的地方的,那么可以考虑他们公用资源的地方,不同的进程享用不同的内存空间,但是同一个进程的不同线程享用的是同一片内存空间,那让其他线程把要处理的消息放到这个特定的内存空间上,处理消息的线程来这个内存空间上来取消息去处理不就可以了吗。“消息收发”和“消息处理”就是弱相关的任务,而“消息处理”里面可能又分为“消息解码”、“业务处理”,这两个任 务相对来说相关性就要强多了。
当然这种划分方式不是一成不变的,也可以根据实际情况进行调整。
4)可能要扩展到多机分布的用进程,多核分布的用线程
原因请看上面对比。
5)都满足需求的情况下,用你最熟悉、最拿手的方式
表 4–2 互斥锁范围比较 solaris posix 定义 usync_processpthread_process_shared 用于同步该进程和其他进程中的线程 usync_process_robust 无posix 等效项 用于在进程间可靠地同步线程 usync_thread pthread_process_private用于仅同步该进程中的线程。实验1编程实现进程(线程)同步和互斥一、实验目的通过编写程序实现进程同步和互斥,使学生掌握有关进程(线程)同步与互斥的原理,以及解决进程(线程)同步和互斥的算法,从而进一步巩固进程(线程)同步和互斥等有关的内容。并发io问题一直是服务器端编程中的技术难题,从最早的同步阻塞直接 fork 进程,到 worker 进程池/线程池,到现在的异步io、协程。
需要提醒的是:虽然我给了这么多的选择原则,但实际应用中基本上都是“进程+线程”的结合方式,千万不要真的陷入一种非此即彼的误区。
消耗资源:
线程是进程的一个实体,是cpu调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程是进程的一个实体, 是cpu调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程是进程的一个实体,是cpu调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.。
而运行于一个进程中的多个线程,它们彼此之间使用相同 的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的 时间。apache是多进程/多线程模型的,它会在启动的时候启动一批进程,作为进程池,当用户请求到来的时候,从进程池中分配处理进程给具体的用户请求,这样可以节省多进程/线程的创建和销毁开销,但是如果同时有大量的请求过来,还是需要消耗比较高的进程/线程切换。由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、 i/o设备等,因此操作系统所付出的开销远大于创建或撤销线程时的开销。
通讯方式:
进程之间传递数据只能是通过通讯的方式,即费时又不方便。线程时间数据大部分共享(线程函数内部不共享),快捷方便。但是数据同步需要锁对于static变量尤其注意
线程自身优势:
提高应用程序响应;使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上;
改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
实验数据:
进程实验代码(fork.c):
#include
#include
#include
#define P_NUMBER 255 //并发进程数量
#define COUNT 5 //每次进程打印字符串数
#define TEST_LOGFILE 'logFile.log'
FILE *logFile=NULL;
char *s='hello linux\0';
int main()
{
int i=0,j=0;
logFile=fopen(TEST_LOGFILE,'a+');//打开日志文件
for(i=0;i
{
if(fork()==0)//创建子进程,if(fork()==0){}这段代码是子进程运行区间
{
for(j=0;j
{
printf('[%d]%s',j,s);//向控制台输出
//fprintf(logFile,'[%d]%s',j,s);//向日志文件输出,
}
exit(0);//子进程结束
}
}
for(i=0;i

{
wait(0);
}
printf('Okay');
return 0;
}
进程实验代码(thread.c):
#include
#include
#include
#include
#define P_NUMBER 255//并发线程数量
#define COUNT 5 //每线程打印字符串数
#define TEST_LOG 'logFile.log'
FILE *logFile=NULL;
char *s='hello linux\0';
print_hello_linux()//线程执行的函数
{
int i=0;
for(i=0;i
{
printf('[%d]%s',i,s);//想控制台输出//fprintf(logFile,'[%d]%s',i,s);//向日志文件输出
}
pthread_exit(0);//线程结束
}
int main()
{
int i=0;
pthread_t pid[P_NUMBER];//线程数组
logFile=fopen(TEST_LOG,'a+');//打开日志文件
for(i=0;i
pthread_create(&pid[i],NULL,(void*)print_hello_linux,NULL);//创建线程
for(i=0;i
pthread_join(pid[i],NULL);//回收线程
printf('Okay');
return 0;
}
两段程序做的事情是一样的,都是创建“若干”个进程/线程,每个创建出的进程/线程打印“若干”条“hellolinux”字符串到控制台和日志文件,两个“若干”由两个宏 P_NUMBER和COUNT分别定义,程序编译指令如下:
gcc -o fork fork.c
gcc -lpthread -o thread thread.c
实验通过time指令执行两个程序,抄录time输出的挂钟时间(real时间):
time ./fork

time ./thread
每批次的实验通过改动宏 P_NUMBER和COUNT来调整进程/线程数量和打印次数,每批次测试五轮,得到的结果如下:
一、重复周丽论文实验步骤
(注:本文平均值算法采用的是去掉一个最大值去掉一个最小值,然后平均)
出的结果是:任务量较大时,多进程比多线程效率高;而完成的任务量较小时,多线程比多进程要快,重复打印 600次时,多进程与多线程所耗费的时间相同。
、增加每进程/线程的工作强度的实验
这次将程序打印数据增大,原来打印字符串为:
char *s = 'hello linux\0';
现在修改为每次打印256个字节数据:
char *s = '1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\
1234567890abcdef\0'; 【实验结论】
linux支持内核级的线程,但它将线程定义为进程的另一个“执行上下文”,从而简化了进程/线程之间的关系和调度程序的设计,它的线程库提供了和posix兼容的线程同步机制。线程:一个进程,可以存在一个或多个线程,线程之间同步执行多种操作,一般地,线程之间是相互独立的,当一个线程发生错误的时候,并不一定会导致整个进程的崩溃。实验1编程实现进程(线程)同步和互斥一、实验目的通过编写程序实现进程同步和互斥,使学生掌握有关进程(线程)同步与互斥的原理,以及解决进程(线程)同步和互斥的算法,从而进一步巩固进程(线程)同步和互斥等有关的内容。
在Linux2.6上,多线程并不比多进程速度快,考虑到线程栈的问题,多进程在并发上有优势。
四、多进程和多线程在创建和销毁上的效率比较
线程池:需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。由于这个线程一旦创建就贯穿进程生命期不会销毁,因此wt_executeinpersistentthread标志的线程池回调也由本线程执行。进程线程间创建的开销不足作为选择的依据,因为一般我们都是使用线程池或者进程池,在系统启动时就创建了固定的线程或进程,不会频繁的创建和销毁。
“监视进线程创建”将icesword运行期间的进线程创建调用记录在循环缓冲里,“监视进程终止”记录一个进程被其它进程terminate的情况。结束语:顺便提一下为什么会有inetd服务器的原因,因为如果没有的话,假设在系统中有10个请求服务端,然后就会创建10个接受进程来接受服务,这样系统就多了10个进程,那么如果没有请求来的话这10个进程还在挂起状态,严重的浪费了系统的资源, 所以人们就想用一个进程来做,所以就出来了个inetd服务器的东西,就是说它读取/etc/inetd.conf文件读取10个进程的服务项,然后创建socket等等,这样系统中只是一个进程在挂起,来请求时,就调用相应的任务进程即可,这样节省了系统的资源。一般我们看到的ios单列中并未有加@synchronized(self),然而这样如果是多个线程同时来调用该单列,就会出现问题,创建的实例就不只是单列了,加了线程锁后让该单列始终只能返回一个实例,即单例:假如线程a来调用shareusercontext,这句话时候,会判断 segtoninstance == nil的情况,若没有创建则会创建实例,然而另外的一个线程b也来调用这句话时候,没有线程锁的情况会使其并发调用,即创建了两个实例。
stevens已驾鹤西去多年,但《Unix网络编程》一书仍具有巨大的影响力,上表中stevens比较了三种服务器上多进程和多线程的执行效率,因为三种服务器所用计算机不同,表中数据只能纵向比较,而横向无可比性,stevens在书中提供了这些测试程序的源码(也可以在网上下载)。书中介绍了测试环境,两台与服务器处于同一子网的客户机,每个客户并发5个进程(服务器同一时间最多10个连接),每个客户请求从服务器获取4000字节数据,预先派生子进程或线程的数量是15个。
apache是多进程/多线程模型的,它会在启动的时候启动一批进程,作为进程池,当用户请求到来的时候,从进程池中分配处理进程给具体的用户请求,这样可以节省多进程/线程的创建和销毁开销,但是如果同时有大量的请求过来,还是需要消耗比较高的进程/线程切换。在linux系统中,posix线程可以“看做”为一种轻量级的进程,pthread_create创建线程和fork创建进程都是在内核中调用__clone函数创建的,只不过创建线程或进程的时候选项不同,比如是否共享虚拟地址空间、文件描述符等。oracle的服务进程由oracle实例自动创建,用来处理连接到实例的用户进程发出的请求,用户必须通过连接到oracle的服务进程来获取中的信息.对于专用服务器模式,用户进程和oracle进程是一一对应,而在共享服务器模式下,一个oracle服务进程可能同事服务多个用户进程.。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-105369-1.html
伊国的安全谁保证
请把你的这条高论建议给奥巴马和安倍