进程和线程
来源:互联网 发布:网络代理软件 编辑:程序博客网 时间:2024/06/06 05:55
【描述】线程和进程是一个老生常谈的话题,线程和进程的区别和优缺点有哪些?线程最多可以开多少个?
【解析】
1 区别
线程是CPU调度的最小单位,进程是资源分配的最小单位。进程是线程的容器,真正完成代码执行的是线程,而进程则作为线程的执行环境。在32位的Windows操作系统中,系统要为每一个进程分配私有的232=4GB的虚拟地址空间。但实际上只有2GB的空间被用户分区使用,另外2GB空间被用于内核代码、设备驱动程序等内核分区。在进程中,线程共享用户分区这一地址空间。
2 优缺点
在Windows系统中,对于多进程程序而言,系统要为进程分配私有的4GB虚拟地址空间,占用的资源较多。而对于多线程的程序,多线程共享同一进程的地址空间,因此占用的资源较少。当进程切换时,需要交换整个地址空间,而线程之间切换只是执行环境的改变,因此效率较高。整体而言,在Windows系统中,多线程优于多进程,毕竟Windows系统是从多线程开始的。
在Linux系统中,采用POSIX标准,Unix家族都是从多进程过来的。多进程调度开销比多线程调度开销,没有显著区别。
一个形象的比喻,
多进程是立体交通系统,虽然造价高,上坡下坡多耗点油,但是不堵车。
多线程是平面交通系统,造价低,但红绿灯太多,老堵车。
所谓的耗油多是指CPU的主频,但现在主频已不是问题,而内存也是越来越大。我们更希望行车过程畅通无阻。
3 线程栈
线程栈用于维护线程在执行代码时需要的所有函数参数和局部变量。在32位的系统中,进程中,线程最多能开多少个?
这个没有固定的答案,
线程的个数 = 进程用户空间/线程栈的大小。
在Windows平台默认的栈大小为1M,以此计算,理论上,可以开辟2GB/1M=2048个线程。但实际上,是无法做到的。因为有其他部分的消耗。
在Linux平台,如Fedora 10,利用ulimit -a指令可以查看堆栈的大小,结果为
stack size (kbytes, -s) 10240
也就是10M。以此计算,最多开辟2GB/10MB=204个线程。另外查阅文档,反映Linux平台的栈默认大小应该是8192KB,而不是10M。
【实例剖析】
到底可以开多少个,不妨测试一下:
测试环境:Fedora10+虚拟机+512MB(虚拟内存估计是1024MB)
test.c
#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <assert.h>void *start_routine(void *param){int data = *(int *)param;printf("%s:%d\n", __func__, data);return NULL;}#define THREADS_NR 1024void create_test_threads(){int i = 0;int ret1 = 0;void *ret2 = NULL;pthread_t ids[THREADS_NR] = {0};for(i = 0; i < THREADS_NR; i++){ret1 = pthread_create(ids + i, NULL, start_routine, &i);}for(i = 0; i < THREADS_NR; i++){pthread_join(ids[i], &ret2);}return ;}int main(int argc, char **argv){create_test_threads();return 0;}
Makefile
src = test.ctarget = testtemp = $(wildcard *~)flag = PTHREAD_TESTall:$(src)gcc -g -pthread -D$(flag) $^ -o $(target)clean:rm $(temp) $(target)
运行结果
start_routine:300start_routine:301start_routine:302start_routine:303start_routine:304段错误
实验证实在该的环境中,最多可以开辟305个线程。利用GDB调试:
gdb test
start_routine:303[Thread 0xbe409b90 (LWP 11075) exited][New Thread 0xbee0ab90 (LWP 11076)]start_routine:304[Thread 0xbee0ab90 (LWP 11076) exited][New Thread 0xbf80bb90 (LWP 11077)]start_routine:565[Thread 0xbf80bb90 (LWP 11077) exited]Program received signal SIGSEGV, Segmentation fault.0x00581b07 in pthread_join () from /lib/libpthread.so.0Missing separate debuginfos, use: debuginfo-install glibc-2.9-2.i686(gdb) bt#0 0x00581b07 in pthread_join () from /lib/libpthread.so.0#1 0x0804859f in create_test_threads () at test1.c:29#2 0x080485d1 in main () at test1.c:37(gdb) frame 1#1 0x0804859f in create_test_threads () at test1.c:2929pthread_join(ids[i], &ret2);(gdb) p ret1$4 = 11(gdb) p ret2$5 = (void *) 0x0
错误发生在创建时,错误码为11
查看errno.h
利用find查看路劲
(1) find / -name errno.h 2>/dev/null
/usr/src/kernels/2.6.27.5-117.fc10.i686/include/linux/errno.h/usr/src/kernels/2.6.27.5-117.fc10.i686/include/asm-x86/errno.h/usr/src/kernels/2.6.27.5-117.fc10.i686/include/asm-generic/errno.h
(2) 查看源文件
执行
cat /usr/src/kernels/2.6.27.5-117.fc10.i686/include/asm-generic/errno.h
发现11定义在同级目录下errno-base.h文件
查看
cat /usr/src/kernels/2.6.27.5-117.fc10.i686/include/asm-generic/errno-base.h
#define EAGAIN 11 /* Try again */
利用man pthread_create查看,
ERRORS The pthread_create() function shall fail if: EAGAIN The system lacked the necessary resources to create another thread, or the system-imposed limit on the total number of threads in a process {PTHREAD_THREADS_MAX} would be exceeded. EINVAL The value specified by attr is invalid. EPERM The caller does not have appropriate permission to set the required scheduling parameters or scheduling policy. The pthread_create() function shall not return an error code of [EINTR]. The following sections are informative.
说明是内存不足的问题。
转载请标明出处,仅供学习交流,勿用于商业目的
Copyright @ http://blog.csdn.net/tandesir
- 进程和线程
- 关于进程和线程
- 进程和线程
- 进程和线程
- 小解进程和线程
- 进程和线程
- 理解进程和线程
- 进程和线程
- 进程和线程
- 进程和线程 编程
- 进程和线程
- 进程和线程
- 线程和进程
- 进程和线程编程
- 程序、进程和线程
- 进程和线程 区别
- 进程和线程编程
- 什么是线程和进程
- 深入剖析C/C++函数的参数传递机制
- 很动人的伤感爱情故事_等待着,寻找着久别的恋人
- Android Bluetooth编程
- postgresql之pg_dump命令详解
- 演练:创建和使用静态库 (C++)
- 进程和线程
- 业务范围
- 图像轮廓获取opencv
- Linux MTD下获取Nand flash各个参数的过程的详细解析
- ALSA架构文章集锦 以备后用
- 棋盘划分----分治算法
- 二分查找
- pvfs2.7.1 ubuntu11.10 fail to link lio-listio
- android LinearLayout