由于我无法找到解决套接字描述符的线程特定数据的方法,如本问题A question on shared library and thread specific data中所述,我计划声明一个进程范围的全局数组,每行包含两个元素pthread_t和int(for socketfd)。因此,每当线程需要与服务器通信时,它将使用其标识(pthread_self())在其数组中查找其套接字fd并使用它进行通信。
但我想知道,无论何时分别建立连接或断开连接,都不会为此结构动态分配和释放空间,如果我有一个大小为1000的数组......是否太大/效率低(我会还要搜索)? 1000个线程不会同时存在。所以数组并不总是满的。
由于
答案 0 :(得分:3)
除非您在资源有限的硬件上运行,否则只存储1000个元素所需的存储数组所需的空间不会成为问题。至于性能,它实际上取决于你搜索数组的频率......如果在每个线程的生命周期中搜索不会频繁发生,速度可能就足够了,除非你有很高的性能标准。
但是,如果您计划为每个连接创建一个线程并在完成时终止该线程,那么更好的方法是设计一个包含线程从主程序需要的所有信息的结构(如套接字文件)描述符)并在创建线程时将指针作为线程的参数传递给它。
如果你确实每个连接都使用一个线程,你可能也想研究为线程设置一个小于默认值的堆栈大小,这样创建大量线程不会占用太多内存堆栈空间。
答案 1 :(得分:2)
首先,1000个元素所需的内存乘以pthread_t和int的空间是无关紧要的,除非您在嵌入式计算机或其他类似约束的系统上。
关于搜索时间,通过1000个元素的简单搜索可能不会花费很长时间。但是,通过将其实现为hash table,您可以非常快速地实现它。
您可能还会考虑尽管内存分配很慢,但在大多数操作系统上创建新线程的速度也很慢。 (但你可以使用thread pool来避免这种情况。)与后者相比,内存分配的成本可能低于你的想象。与查找该线程的上下文相比,您创建新线程的频率是多少?
另一个评论:如果你真的关心性能,那么创建一个单独的线程来处理每个连接几乎肯定不是要走的路,因为线程之间的上下文切换成本。理想情况下,您希望避免上下文切换,但要保持所有CPU忙碌。这意味着您需要与CPU相同数量的线程,并且每个线程都在进行异步(非阻塞)I / O.
答案 2 :(得分:1)
数组会占用空间,但速度最快。由于1000个元素可以完全购买到内存中,并且不会作为操作系统交换的一部分驻留在磁盘上,因此最多会导致高速缓存未命中的成本。当多个线程查找其信息时,由于随机访问而不会产生任何费用,因为1000行的地址是按顺序的;相隔不远。
另外,当你每行malloc()时,你分配的每一行不需要与先前分配的块连续,当多个线程查找它们各自的信息时,由于这种动态,会有某种随机的内存访问。分配
除非你有内存限制,否则不需要使用malloc()。数组方法简洁且性能友好。
HTH
答案 3 :(得分:1)
一般来说,如果需要从不同的线程更新,从性能的角度来看,在多个线程之间共享的单个数据结构是不好的。从一个线程更新结构将强制其他CPU使其缓存无效,并且诸如互斥锁之类的同步原语会产生额外的开销和内存障碍。如果将元素与缓存行对齐,则可以稍微好一些,但这是特定于硬件的。
话虽如此,我相信与连接设置成本相比,这种开销可以忽略不计。但不要相信我,相信你的探查者