找回密码
 注册
查看: 1706|回复: 9

关于线程和阻塞的问题……

[复制链接]
发表于 2004-6-24 01:17:11 | 显示全部楼层 |阅读模式
1.Linux下一个进程可以创建多少个线程?根据我在网上查到的资料,至少有1024个,但是我的测试程序里只创建了255个线程就不能再创建了,errno显示原因是内存不足,我查看了一下,发现这时程序占用的内存空间竟然是2GB!可我的物理内存只有256M,swap分区只有512M……我看了一下,每多一个线程程序就要多占8M空间,这样算来,8*255=2040M=1.992GB…………这些内存占用数据我都是在“系统监视器”里看到的……我的系统:FedoraCore2( Kernel:2.6.7 ),Duron 750,256M物理内存,512M swap分区,40G的root分区……我无论如何都想不通为什么仅仅255个线程就会占用2GB。而且这些线程里没有任何代码,具体的说,交给每个线程的函数就是:
[code:1]
void* test(void* data)
{
//这里什么都没写,我本以为会线程会立即结束的……
}
[/code:1]
我本以为这些线程创建后会立即结束,结果似乎不是这样……
于是我在函数里面增加了一句:
[code:1]
void* test(void* data)
{

  pthread_exit(NULL);
}
[/code:1]
结果还是一样……

2.在另一个论坛听人说,如果阻塞地读取socket,那么在阻塞的状态下这个读取函数还是要占用一点CPU资源的。我之前说,想做网游,在服务器端,与客户端通过TCP连接通信,为每个连接分配一个线程,用线程阻塞地读取socket,于是别人说这样会浪费不少CPU资源……
我想问一下,真是这样吗?我一直觉得阻塞状态下是不会消耗CPU资源的,刚才通过默难问了CoolQ,CoolQ也这么认为……
如果我在服务器端建立上千个TCP连接,并用上千个线程来阻塞地读取它们,那么是否效率会很低?如果再为每个socket再分配一个线程用于阻塞地write呢?

3.如果使用两个线程,线程A对某个socket执行read,线程B对同一个socket执行write,能这样吗?一个socket能同时被读和写吗?
发表于 2004-6-24 09:12:38 | 显示全部楼层
1 每个线程需要自己的栈空间,跟你执行什么无关,另外,大侠大概忘记了系统是按需分页的,虽然预留了空间,但因为没有访问,系统并没有真的为它分配内存。

2 没错,使用select的阻塞调用效率不好,这也是kevent引入的原因(linux不知道,所有的bsd因为select效率低下而推荐改用kevent)。另,tcp本身就是很耗cpu的操作。

3 应该可以。
回复

使用道具 举报

发表于 2004-6-24 10:40:21 | 显示全部楼层
学习   
回复

使用道具 举报

 楼主| 发表于 2004-6-25 05:10:49 | 显示全部楼层
谢谢~
1.既然只是预留内存空间,那么为什么创建255个线程后就不能再创建新的线程了呢?而且出错的原因还是内存不足……
2.kevent是什么?

再问几个问题
4.C++里的流可以打开文件,那么怎么打开网络连接呢?socket返回的只是int啊……
5.我想构造一个多线程安全的队列,请问有什么现成的设计吗?Linux下进程间的管道似乎也是队列,它是怎么设计的呢?
6.select()要用到FD_SET,那么等select()返回后,FD_SET也被改动过了,那么要再次检测那些连接,是否需要重新设置整个FD_SET?
7.我看APUE后,猜想FD_SET里一个fd只是对应一个bit,所以我想这个FD_SET似乎天生就有多线程安全的特性……只是有个问题,如果我在select()被阻塞的过程中在另一个线程里修改了FD_SET,那会怎样?
回复

使用道具 举报

发表于 2004-6-25 10:48:10 | 显示全部楼层
唉,常常发觉自己知道的太少。

在《posix多线程程序设计》(于磊 曾刚译)第七章 中有一个多线程的工作队列管理器实现代码,不知和你的要求是否一致。
《unix操作系统设计》 (Bach)5.12(p114)说System V 中的pipe 用的循环队列(每个节点是个direct block)
后面也只能猜   
我想6和你说的一样吧,7应该不让其它的线程访问。
其它,未知
回复

使用道具 举报

 楼主| 发表于 2004-6-25 19:03:13 | 显示全部楼层
《posix多线程程序设计》这本书有电子版的吗?或者你知道它里面那个工作队列管理器的细节吗? :-)
回复

使用道具 举报

发表于 2004-6-25 21:00:33 | 显示全部楼层
[quote:5819da3d68="sjinny"]谢谢~
1.既然只是预留内存空间,那么为什么创建255个线程后就不能再创建新的线程了呢?而且出错的原因还是内存不足……
[/quote]

linux下有好几种线程实现,你只能去查相应的文档了。
[quote:5819da3d68="sjinny"]
2.kevent是什么?
[/quote]
不好意思,应该是kqueue,http://people.freebsd.org/~jlemon/papers/kqueue.pdf


再问几个问题
[quote:5819da3d68="sjinny"]
4.C++里的流可以打开文件,那么怎么打开网络连接呢?socket返回的只是int啊……
[/quote]

流是个上层的软件抽象概念,socket是底层的东西。
[quote:5819da3d68="sjinny"]

5.我想构造一个多线程安全的队列,请问有什么现成的设计吗?Linux下进程间的管道似乎也是队列,它是怎么设计的呢?
6.select()要用到FD_SET,那么等select()返回后,FD_SET也被改动过了,那么要再次检测那些连接,是否需要重新设置整个FD_SET?
7.我看APUE后,猜想FD_SET里一个fd只是对应一个bit,所以我想这个FD_SET似乎天生就有多线程安全的特性……只是有个问题,如果我在select()被阻塞的过程中在另一个线程里修改了FD_SET,那会怎样?[/quote]

因为select是个系统调用,所以不能这么用,因为调用返回的时候会往你的内存空间里写东西。
回复

使用道具 举报

 楼主| 发表于 2004-6-26 02:21:27 | 显示全部楼层
我看了那个pdf文件,我并不惧怕e文,我惧怕的是用不了星际译王……
我看了epoll的info,看那意思似乎是比select()和poll()强,难道是event-driven的?kqueue是不是差不多的?不过似乎linux下用不了kqueue……汗,刚刚想问个问题的,一定神就忘了……

再次感谢~
回复

使用道具 举报

发表于 2004-6-27 12:18:40 | 显示全部楼层
[quote:5948b16011="sjinny"]谢谢~
1.既然只是预留内存空间,那么为什么创建255个线程后就不能再创建新的线程了呢?而且出错的原因还是内存不足……
[/quote]

你的 linux 内核应该编译支持的最大内存是 2G,因此就算没有去分配这些内存,内核也不能管理大于2G 的内存了.
回复

使用道具 举报

 楼主| 发表于 2004-6-28 19:05:16 | 显示全部楼层
还要重编译内核啊?
回复

使用道具 举报

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

本版积分规则

GMT+8, 2025-2-15 13:32 , Processed in 0.044793 second(s), 15 queries .

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5.

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