目录
<一>__thread关键字使用
1.__thread 关键字(是GCC内置的线程局部存储设施,存取效率可以和全局变量相比。)
该关键字用于修饰变量,用于表示,再多线程情况下,多个线程都独享一份修饰的变量,不会出现资源竞争的情景.一般用于修饰带有全局切值可变的,但是又不值得用全局变量保护保护的变量.
特点:
a.该关键字只能修饰POD类型(指针变量,不带自定义的构造,拷贝,赋值,析构的类型,二进制内容可以任意复制)b.不能用于修饰class类型对象(指针变量可以),因其无法自动调用构造跟析构函数。
c.可用于修饰全局变量,函数内的静态变量,不能修饰函数内的局部变量或者class的普通成员变量,并且__thread变量值只能初始化为编译器常量。
使用举例:
__thread int i;
extern __thread struct state s;
static __thread char *p;
static __thread ClassAAA * pa = NULL;
2.代码举例
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
__thread int g_local = 0;
void *fun(void *pArg)
{
g_local += 1;
cout << "fun->g_local = " << g_local << endl;
pthread_exit((void *)1);
}
void *hun(void *pArg)
{
g_local += 2;
cout << "hun->::g_local = " << g_local << endl;
pthread_exit((void *)2);
}
int main(void)
{
pthread_t pid1,pid2;
pthread_create(&pid1, NULL, fun, NULL);
pthread_create(&pid2, NULL, hun, NULL);
pthread_join(pid1, NULL);
pthread_join(pid2, NULL);
return 0;
}
hun->g_local = 2
fun->g_local = 1<二>有关tcp/udp网络连接问题
1.网络-Tcp&Udp可以同时绑定同一个端口吗?
答案:可以的。
原因:
在数据链路层中,通过 MAC 地址来寻找局域网中的主机。在网络层中,通过 IP 地址来寻找网络中互连的主机或路由器。在传输层中,需要通过端口进行寻址,来识别同一计算机中同时通信的不同应用程序。
所以,传输层的「端口号」的作用,是为了区分同一个主机上不同应用程序的数据包。
传输层有两个传输协议分别是 TCP 和 UDP,在内核中是两个完全独立的软件模块。
当主机收到数据包后,可以在 IP 包头的「协议号」字段知道该数据包是 TCP/UDP,所以可以根据这个信息确定送给哪个模块(TCP/UDP)处理,送给 TCP/UDP 模块的报文根据「端口号」确定送给哪个应用程序处理。
2.多个客户端可以同时绑定相同端口吗?
答案:可以的
原因:
客户端的端口选择的发生在 connect 函数,内核在选择端口的时候,会从 net.ipv4.ip_local_port_range 这个内核参数指定的范围来选取一个端口作为客户端端口。
<++>TCP 连接是由四元组(源IP地址,源端口,目的IP地址,目的端口)唯一确认的,那么只要四元组中其中一个元素发生了变化,那么就表示不同的 TCP 连接的。例如客户端已使用端口 28888 与服务端 A 建立了连接,那么客户端要与服务端 B 建立连接,还是可以使用端口 28888 的,因为内核是通过四元祖信息来确定一个 TCP 连接的,所以并不会因为客户端的端口号相同,而导致连接冲突的问题。
3.如何解决客户端 TCP 连接 TIME_WAIT 过多,导致无法与同一个服务器建立连接的问题?
答案:打开内核配置net.ipv4.tcp_tw_reuse参数。
因为开启了这个内核参数后,客户端调用 connect 函数时,如果选择到的端口,已经被相同四 元组的连接占用的时候,就会判断该连接是否处于 TIME_WAIT 状态,如果该连接处于 TIME_WAIT 状态并且 TIME_WAIT 状态持续的时间超过了 1 秒,那么就会重用这个连接,然后就可以正常使用该端口了。
4.服务器端只有一个端口,收发请求不会乱吗?
答案:三个部分,分别如下
第一、服务器端在接收到新连接的时候会创建新的 socket 出来。这个新的socket 上有完整的四元组(内部源 IP、源端口、目的 IP 和目的端口)信息,并以 hashtable 的方式管理。
第二、TCP 网络包体内部源 IP、源端口、目的 IP 和目的端口等信息都是携带在包头里的。
第三。内核在接收到网络包的时候,在协议栈处理的时候会解析包头,根据这个包头中完整的四元组和内核中 hashtable 中管理的 socket 进行匹配,只有四元组信息完全一致,才能把接收到的数据放到该 socket 的接收队列中。不同的请求的 socket 上四元组信息并不完全一致,所以请求之间不会相互干扰。