- 论坛徽章:
- 9
|
本帖最后由 wlmqgzm 于 2015-11-10 20:43 编辑
谈一点核心关键技术的东西, 就是无锁的安全和高性能机制是如何实现的:
下面对socket中的各个变量进行了详细分析, 在代码中对socket的数据进行了集中管理, 并且没有使用锁,
线程使用策略:
有3类线程:管理线程, socket线程, 主线程.
管理线程是单线程,
socket线程使用 多个io_service, 每个io_sevice单线程策略, 实现单线程处理.
主线程默认只有一个是单线程.
内存使用策略:
一方面避免False Sharing, 另外一方面就是"内存屏障"是否设置的问题.
其实, 我的理解, 基本上这里的每个变量都不需要设置"内存屏障", 因为这些变量都是原子变量, 都对更新速度不敏感, 过一会才更新, 对程序运行结果无影响.
另外一方面, 使用这些变量的函数中, 后面都有post/async_write/async_write/async_accept等内部有"内存屏障"的处理代码.
但是, 考虑到规范化也很重要, 在任何情况下, 以及有新增删改代码都不会出现问题, 为了可靠性, 最后还是在所有的使用这些变量的程序中都设置了"内存屏障", 降低了一点运行速度
下面是每个socket的主要数据:
// 这里使用alignas(64), 浪费了内存, 但是解决了false sharing,
class alignas(64) Struct_socket_data
{
public:
unsigned int int_second_receive; // socket单线程内部变量, 对外每秒一次用post传递给管理线程, 最多每秒更新数万次
unsigned int int_socket_receive; // socket单线程内部变量, 不对外, 最多每秒更新数万次
unsigned int int_second_receive_byte; // socket单线程内部变量, 对外每秒一次用post传递给管理线程,最多每秒更新数万次
unsigned int int_socket_receive_byte; // socket单线程内部变量, 不对外, 最多每秒更新数万次
unsigned int int_second_send; // socket单线程内部变量, 对外每秒一次用post传递给管理线程,最多每秒更新数万次
unsigned int int_socket_send; // socket单线程内部变量, 不对外, 最多每秒更新数万次
unsigned int int_second_send_byte; // socket单线程内部变量, 对外每秒一次用post传递给管理线程,最多每秒更新数万次
unsigned int int_socket_send_byte; // socket单线程内部变量, 不对外 ,最多每秒更新数万次
std::vector<char> vt_read; // socket单线程内部变量, 不对外, 最多每秒更新数万次
std::vector<char> vt_left; // socket单线程内部变量, 不对外, 最多每秒更新数万次
std::vector<char> vt_write; // socket单线程内部变量, 不对外,最多每秒更新数万次
volatile bool bool_socket_debug; // socket单线程内部变量, 不对外, 外部用post设置此参数, 很少使用,
volatile bool bool_in_read_wait; // socket单线程更新, 管理线程只读, 共享变量, 最多每秒更新数万次, 整个连接过程中管理线程一般只读一次(管理线程先要满足超时等因素才读,此时此变量已经很久未更新了), 对更新速度不敏感,, 使用写内存屏障
volatile bool bool_in_write_wait; // socket单线程更新, 管理线程只读, 共享变量, 最多每秒更新数万次, 整个连接过程中管理线程一般只读一次(管理线程先要满足超时等因素才读,此时此变量已经很久未更新了), 对更新速度不敏感,, 使用写内存屏障
alignas(64)
volatile std::time_t time_read_wait_begin; // socket单线程更新, 管理线程只读, 共享变量, 大约每秒更新一次, 每秒读一次 , 对更新速度不敏感,, 使用写内存屏障
volatile std::time_t time_write_wait_begin; // socket单线程更新, 管理线程只读, 共享变量, 大约每秒更新一次, 每秒读一次 , 对更新速度不敏感, 使用写内存屏障
volatile unsigned long long u_seconds_shutdown_receive_begin; // socket单线程更新, 管理线程只读, 共享变量, 整个连接过程中最多更新一次, 对更新速度不敏感 , 使用写内存屏障
volatile unsigned long long u_seconds_shutdown_send_begin; // socket单线程更新, 管理线程只读, 共享变量, 整个连接过程中最多更新一次, 对更新速度不敏感 , 使用写内存屏障
volatile bool bool_socket_shutdown_receive; // socket单线程更新, 管理线程只读, 共享变量, 整个连接过程中最多更新一次, 对更新速度不敏感 , 使用写内存屏障
volatile bool bool_socket_shutdown_send; // socket单线程更新, 管理线程只读, 共享变量, 整个连接过程中最多更新一次, 对更新速度不敏感 , 使用写内存屏障
alignas(64)
unsigned long long u_seconds_accept; // 一直保持初始化值, 管理线程初始化写, 使用写内存屏障
boost::asio::ip::tcp::socket socket1; // 一直保持初始化值, 管理线程初始化写, 使用写内存屏障
int socket_handle_init; // 一直保持初始化值, 管理线程初始化写, 使用写内存屏障
unsigned int int_client_ip; // 一直保持初始化值, 管理线程初始化写, 使用写内存屏障
unsigned short short_client_port; // 一直保持初始化值, 管理线程初始化写, 使用写内存屏障
unsigned short short_server_port; // 一直保持初始化值, 管理线程初始化写, 使用写内存屏障
unsigned short short_vector_ios_id; // 一直保持初始化值, 管理线程初始化写, 使用写内存屏障
bool bool_is_server; // 一直保持初始化值, 管理线程初始化写, 使用写内存屏障
std::string str_client_ip; // 一直保持初始化值, 管理线程初始化写, 使用写内存屏障
std::string str_server_ip; // 一直保持初始化值, 管理线程初始化写, 使用写内存屏障
bool bool_socket_read_wait_timeout; // 管理线程内部变量, 不对外, 整个连接过程中最多更新一次,
bool bool_socket_write_wait_timeout; // 管理线程内部变量, 不对外, 整个连接过程中最多更新一次,
public:
Struct_socket_data( std::shared_ptr<boost::asio::ip::tcp::socket> sp_socket1_in );
}; |
|