|

楼主 |
发表于 2004-4-6 14:26:48
|
显示全部楼层
trap并不是系统调用,而是"信号"触发器。信号来临后,通常调用自己的函数来处理。
trap handler SIGNAL
>>我想你误解我的意思了,我说的系统调用当然不指trap,而是把上面的handler设置为系统调用,有何疑义吗?
呵呵,楼顶帖子斑竹提及,"执行某程序的编译安装(此过程将耗时较长)时,希望可以同时去执行另外一个程序,成功后返回",试想有这样奇怪的进程吗?
难道真的没有吗?举个简单类似的例子,比如我们在浏览网页的时候,网页上除了基本的html文本外还有大量的比如图象,视频文件。那么我们打开网页的时候,并不时让网页从上而下显示,而是将文本与其他媒体(这里是图象和视频)分几个线程同时下载,所以我们往往看到文本先显示,但当所有的东西都显示完后,浏览器状态才显示100%,即标志此进程已完成。不知道此例有无不妥,有请指出。
线程是进程的内部实例,它由进程的静态时(程序)的内容所决定,然后调用内核或者glibc的线程库来创建线程,并不需要人工干预,因为这是无法想象的(线程的协作复杂度甚于进程),更是无意义的(要操作线程还不如操作进程,因为我们每键入一个命令就创建一个进程)。
我的看法是,进程是面向用户的,线程是面向进程本身的。
你所说的过于片面,线程是进程的内部实例,这句话很大程度上是错误的。在多线程OS中,进程只作为系统资源分配的单位,给线程提供资源而已,并不是一个可执行的实体,而真正的可执行实体却是线程。你说的“人工干预”不知为何意?难道人没办法控制线程吗?难道线程的控制真的就那么的困难吗?那么请看下面的线程控制的实例:
- #include <pthread.h>
- #include <stdio.h>
- int sum;
- void *runner(void *param);
- main(int argc,char *argv[])
- {
- pthread_t tid;
- pthread_attr_t attr;
- if(argc !=2){
- fprintf(stderr,"usage:a.out<integer value>\n");
- eixt();
- }
- if(atoi(argv[1])<0){
- fprintf(stderr,"%d must be <=0\n",atoi(argv[1]));
- exit();
- }
- pthread_attr_init(&attr);
- pthread_create(&tid,&attr,runner,argv[1]);
- pthread_join(tid,NULL);
- printf("sum=%d\n",sum);
- }
- void *runner(void *param);
- {
- int i;
- sum=0;
- if (upper>0){
- for(i=1;i<=upper;i++)
- sum+=i;
- }
- pthread_exit(0);
- }
复制代码
以上程序轻松的实现了线程的创建、以及执行、退出。为何不能?
由于历史缘故,UNIX的多进程机制比多线程机制更完善。
Unix并无多线程机制!
#####以下引用王波--<<FreeBSD使用大全>>#####
在Unix中,是使用的进程概念来区分不同的独立计算任务,进程具有独立的上下文空间、独立数据空间等等特性,这样进程就可以很容易的独立执行,内核就可以根据优先级在进程之间进行切换,因此进程也就是最基本的内核调度实体。但是,由于计算任务的复杂性,很多任务需要使用多个进程完成,而且这些进程之间需要交换数据。为了解决这个问题,Unix中又设计了多种进程间的通信方式,称为IPC,例如管道、共享内存、套接字等等,这些内容本身就可以独立使用一本专门的书籍来描述了。
因此对于一些比较复杂的程序,就形成了一个怪圈,为了隔离计算任务,设计了进程的概念,为了进程之间能够共享数据,又设计了多种IPC通信方式。因此,人们就希望能设计一种能够独立执行,但没有独立数据空间的轻量级进程的概念,这就是线程。
明显的,线程对于复杂系统来讲非常有意义,因为不再需要复杂的IPC通信方式维护进程之间的数据交换,同时多个线程也可以独立、并行的执行。目前,很多数据库系统、Java应用程序都需要线程支持。但是由于Unix系统本身并不存在线程这个概念,那么在Unix下引入线程就有两种比较直接的方式。
第一种方式是不在内核中实现线程,而在用户程序本身中实现线程,这实际是对线程的一种模拟,线程之间的切换和调度是在用户的进程内部进行的,这种方式就被称为用户空间的线程。这种线程的好处是实现非常简单,而且性能也非常好,因为线程之间的切换都在用户进程内部进行,切换开销比较小。FreeBSD下缺省就使用这种线程模式。
它的缺点也很明显,首先就是不能充分利用高端服务器系统的SMP多处理器的优点,因为一个进程只能由一个处理器处理,第二点由于用户空间线程是在用户空间切换,某个线程遇到一个需要阻塞的系统调用而就会造成整个进程被阻塞,因而其他线程也被阻塞,这中情况实际在线程的概念中是不允许的,但实际实现中很难被百分之百避免。
第二种实现方式是通过修改进程的实现方式来完成,可以使用不完全的进程创建方式创建共享数据空间的进程,在Linux下这种系统调用为clone(),而在FreeBSD下它为rfork()。这种方式是Linux的基本线程处理方式,FreeBSD下可以使用linuxthread的兼容库来实现这种线程。
#####引用结束!
严格来说,Linux也没有真正的多线程
Linux的线程实现无非就是通过fork()或者clone()系统调用来实现的。fork()的仅仅是实现进程的复制,把父进程中的所有数据结构复制到新进程中而已,并没有产生线程!clone()也只不过实现了进程的复制而已,但它复制的新进程(即我们认为的线程)中的数据区只是一个指向父进程中数据区的指针而已!所以在Linux下实际上就没有线程的概念!真正实现线程的是WinNT/2000或者Solaris这些!它们本身就是以线程为基础进行任务调度的,性能较好比较正常。SUN Solaris的线程实现则提供了另一个很好的参考平台,在Solaris中,事实上是混用了用户空间的线程和进程基础的线程的,使用多个进程运行更多的线程,因此可以综合利用多处理器的优点和在进程内部切换线程的优点。
|
|