自己从事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还要高呢?虽然这个表面现象可以回答为何大家喜欢进程编程而少用线程编程,但究其然到底是为什么呢?还有我这个测试方法到底对了没有呢?(我也是用自己的普通PC机在测啊)看来还得仔细研究内核源代码才知道啊。
查到有资料说:由于Linux特有的优点, Linux的进程是比较高效和轻量级的,所以Linux首选进程编程。
Linux/UNIX编程为什么多用进程少用线程
内容版权声明:除非注明,否则皆为本站原创文章。