LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 872|回复: 5

Linux下编程为什么多用进程少用线程?编程问题探讨一

[复制链接]
发表于 2005-11-11 23:47:57 | 显示全部楼层 |阅读模式
自己从事Linux/UNIX编程多年,一直用fork在写多进程的程序。当有朋友问起为何Linux下很少用线程编程时才发现自己还真需要研究一下这问题。通过man手册查看fork得到如下提示:
fork  creates  a  child  process that differs from the parent process only in its PID and PPID, and in the fact that resource utilizations are set to 0.  File locks and pending signals are not inherited.
Under Linux, fork is implemented using copy-on-write pages, so the only penalty incurred by fork  is  the  time and memory required to duplicate the parent's page tables, and to create a unique task structure for the child.
也就是说fork做的事只有复制页表(page tables)和创建task structure。另外,父子进程表面看来唯一不同的是PID和PPID而资源消耗为0了。
而查看LinuxThreads的PTHREAD_CREATE(3)只得到是创建一个线程,并没有提到相关详细内容。
实际情况如何呢?我编写了如下两段代码:
/*forktest.c代码如下:*/
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char ** argv)
{
        pid_t        pid;
        char *        mem;
        if(argc < 4)        {printf("\r\nusage: %s time1 time2 memory-size\n", argv[0]); return 1;}
        mem = (char *)malloc(atoi(argv[3])); /*为了测试内存占用情况,故意输入1G或更多内存需求*/
        pid = fork();
        if(pid == 0)    {
                sleep(atoi(argv[1]));
                exit(0);
        }
        sleep(atoi(argv[2]));
        return 0;
}
/*此代码编译生成可执行程序a-fork*/

/*pthread_create.c代码如下:*/
#include <unistd.h>
#include <pthread.h>
void * start_routine(void * a)
{
        sleep(30);
}

int main(int argc, char ** argv)
{
        int ret;
        pthread_t pth;
        ret = pthread_create(&pth, NULL, start_routine, NULL);
        sleep(35);
        return 0;
}
/*此代码编译生成可执行程序a-thread*/

然后分别运行上述两个程序,用ps命令和top命令观察,得到如下表面结论:
1、两者的CPU占有率%CPU都0
2、两者的内存占有率%MEM:a-fork为0.5而a-thread为0.6
3、两个程序运行后ps都能看到两个进程(即a-fork进程有两个,a-thread进程也有两个)

深入理解看到的现象:
有上述结果3的原因是由于LinuxThreads所采用的就是线程和进程"一对一"模型,调度交给核心,而在用户级实现一个包括信号处理在内的线程管理机制。
有上述结果1应该是程序都在sleep,没有占用CPU是可以理解的吧。
但为什么会出现第2个结果,即a-thread的内存占有率居然比a-fork还要高呢?虽然这个表面现象可以回答为何大家喜欢进程编程而少用线程编程,但究其然到底是为什么呢?还有我这个测试方法到底对了没有呢?看来还得仔细研究内核源代码才知道啊。
发表于 2005-11-11 23:54:15 | 显示全部楼层
我觉得不会吧,线程的那个程序怎么会ps出两个来呢?这里就有问题。
用gdb调试一下呢?
你用什么命令看内存占用的?
回复 支持 反对

使用道具 举报

发表于 2005-11-12 09:20:23 | 显示全部楼层
linuxThread 实现的确实有很多问题,请参考nptl的设计(相信你的想法会有所改变):http://people.redhat.com/drepper/nptl-design.pdf
回复 支持 反对

使用道具 举报

发表于 2005-11-12 12:22:41 | 显示全部楼层
linux下线程和进程没有多大区别
回复 支持 反对

使用道具 举报

发表于 2005-11-12 14:20:34 | 显示全部楼层
1、NPTL 在线程的 POSIX 兼容度和效率方面都有了很大提高,而且 2.6 核心引入了 tid 与线程组概念,使多线程程序的多个线程共享一个 pid
2、为什么多用进程少用线程的根本原因在于,相当于 30 年的 UNIX 历史,线程仍然是个相当新的事务,而且,是在 UNIX 分裂之后才产生的东西,所以在大量共享 UNIX 程序源码和设计思想的同时,fork 的使用也成为了 Linux 软件的主流。
回复 支持 反对

使用道具 举报

发表于 2005-11-12 15:22:36 | 显示全部楼层
据说linux进程本来就是轻量级的(相对于其它os)
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表