最近工作一直在写业务代码,这样不行,基础技术不能丢。
刚好最近手上有了个性能优化的活,需要用多线程来优化加速。刚好趁着这个机会,复习下多线程和线程池。
线程池模型
模型呢本身很简单,就是一个标准的reactor模型。
reactor模型的核心思想,是消息传递。
最近工作一直在写业务代码,这样不行,基础技术不能丢。
刚好最近手上有了个性能优化的活,需要用多线程来优化加速。刚好趁着这个机会,复习下多线程和线程池。
模型呢本身很简单,就是一个标准的reactor模型。
reactor模型的核心思想,是消息传递。
最近使用了gdb进行测试程序调试,这里刚好进行下记录
使用gdb进行调试之前,需要在编译程序时,要加入-g
选项,在可执行文件中添加调试符号表
启动调试也很简单,gdb ./test
即可。如果程序有参数输入,那么则使用gdb --args ./test args1 args2
启动调试之后,按下r
键让程序开始运行。r
即为restart,令程序直接从头开始运行
b
即为breakpoint,进行断点设置。具体的设置方式是,b <源码文件>:<行号>
查看堆栈时,使用bt
命令,会显示出来当前程序的调用堆栈,使用f <堆栈号>
选择相应的堆栈进行查看
选择了对应的堆栈之后,使用info locals
输出当前的局部变量
info threads
显示出当前所有的线程,thread <线程号>
进入对应的线程
c
为continue,执行到下一个断点的位置
n
为next,执行到下一行
s
为step in,若此行有调用函数,则会进入被调用的函数中,进行单步调试
p
为print,打印输入对应的变量或者表达式结果,用法为p <变量名>
Linux系统提供了系统调用,可以查询到设备的域名信息
在头文件netdb.h
中,提供了两个系统调用gethostbyaddr
和gethostbyname
#include <netdb.h>
struct hostent *gethostbyname(const char*name);
struct hostent *gethostbyaddr(const char *addr, int len, 0);
// 调用结果成功,则返回非空指针;错误则返回空指针,且同时设置h_errno。
其中返回的结构struct hostent
用于记录主机信息条目具体为
/* Description of data base entry for a single host. */
struct hostent
{
char *h_name; /* Official name of host. */
char **h_aliases; /* Alias list. */
int h_addrtype; /* Host address type. */
int h_length; /* Length of address. */
char **h_addr_list; /* List of addresses from name server. */
#ifdef __USE_MISC
# define h_addr h_addr_list[0] /* Address, for backward compatibility.*/
#endif
};
下面是一个简单的示例,用于说明这两个系统调用的使用方法
#include <iostream>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
void process_print_res(const struct hostent *res)
{
std::cout << "official name: " <<res->h_name <<std::endl;
for(char **p = res->h_aliases; *p!=nullptr; ++p){
std::cout <<"alias names: " <<*p <<std::endl;
}
std::cout << "addr net type: ";
switch (res->h_addrtype)
{
case AF_INET:
std::cout << "ipv4";
break;
case AF_INET6:
std::cout << "ipv6";
break;
default:
std::cout << "unknown";
break;
}
std::cout <<std::endl;
for(char **p = res->h_addr_list; *p!=nullptr; ++p){
struct in_addr tmp;
tmp.s_addr = ((struct in_addr *)*p)->s_addr;
char *addr = inet_ntoa(tmp);
std::cout <<"address: " <<addr <<std::endl;
}
}
int main(int argc, char *argv[]) {
struct in_addr addr;
struct hostent *p_host;
if(argc != 2){
std::cout <<"usage: " <<argv[0] << " <domain_name or ip>" <<std::endl;
return 0;
}
if(0 != inet_aton(argv[1], &addr)){
// input is a address
p_host = gethostbyaddr((const void*)&addr, sizeof(addr), AF_INET);
if(!p_host){
std::cout<<"get host by addr err" <<std::endl;
return 0;
}
} else {
// input is a hostname
p_host = gethostbyname(argv[1]);
if(!p_host){
std::cout<<"get host by name err" <<std::endl;
}
}
process_print_res(p_host);
return 0;
}