1线程总数异步的。所谓线程安全是指:“代码能够被多个线程调用而不会产生灾难性的结果,它不要求代码在多个线程中高效地运行,只要求能够安全的运行”。实现线程安全有以下几种方式:
(1) 简单粗暴方式: 利用Pthreads提供的工具: 互斥量、条件变量和线程私有数据,实现线程的安全。即通过整个函数的调用的串行化来实现线程安全,在进入函数时候加锁,离开函数时候解锁。这样该函数可被若干个线程调用,但同一个时刻只有一个线程能够调用它。
(2) 稍较为高效方式: 将线程安全函数划分为多个临界区, 这样允许多个线程同时进入该函数,但不能同时进入一个临界区。
(3) 最有效方式: 将代码改造为对临界数据的保护,而不是对临界代码的保护,这样就可以令不会同时访问相同临界数据的线程完全并行地执行。通俗易懂说,就是将互斥锁和数据流相关联,保护数据而不是代码. 如下代码摘录自librdkafka源码中rdkafka_int.h文件中的struct rd_kafka_s结构体声明内部成员列表的一部分。
/* Mutex */
//若当前环境是Win,则声明mtx_t的数据类型格式.
#if defined(_TTHREAD_WIN32_)
typedef struct {
union {
CRITICAL_SECTION cs; /* Critical section handle (used for non-timed mutexes) */
HANDLE mut; /* Mutex handle (used for timed mutex) */
} mHandle; /* Mutex handle */
int mAlreadyLocked; /* TRUE if the mutex is already locked */
int mRecursive; /* TRUE if the mutex is recursive */
int mTimed; /* TRUE if the mutex is timed */
} mtx_t;
//若当前环境是类UNIX环境,则将pthread_mutex_t取别名 mtx_t。
#else
typedef pthread_mutex_t mtx_t;
#endif
/* Condition variable */
#if defined(_TTHREAD_WIN32_)
typedef struct {
HANDLE mEvents[2]; /* Signal and broadcast event HANDLEs. */
unsigned int mWaitersCount; /* Count of the number of waiters. */
CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
} cnd_t;
#else
typedef pthread_cond_t cnd_t;
#endif
//将lock互斥锁和rk_curr_msgs数据流关联起来。
struct {
mtx_t lock; /* Protects acces to this struct */
cnd_t cnd; /* For waking up blocking injectors */
unsigned int cnt; /* Current message count */
size_t size; /* Current message size sum */
unsigned int max_cnt; /* Max limit */
size_t max_size; /* Max limit */
} rk_curr_msgs;
一个线程就不存在线程安全的问题。
同步可以通过多种方式来实现:常见的互斥量、条件变量、信号量和事件。还有消息传递机制,如:UNIX管道、SOCKET、POSIX消息队列,或是其他异步进程间的(本地或是网络)通信协议。可以将线程理解为一种减负的进程,精干、简单、快速。系统在线程间切换要比在进程间切换快速很多,这得益于线程间共享地址空间(包括代码段、数据段、堆栈等等)。
分离一个正在运行的线程不会对线程带来任何的影响,仅仅是通知系统当该线程结束时候,其所属资源可以被回收。
一个没有被分离的线程终止时候会保留其虚拟内存,包括他们的堆栈和其他系统资源。分离线程意味着通知系统不再需要此线程,允许系统将分配给它的资源回收处理。
Linux下与线程相关的命令:
查看最大线程数: cat /proc/sys/kernel/threads-max
根据进程号查询:pstree -p 进程号
线程状态转换图:
(1) 试图加锁一个已经上锁的互斥量;
(2) 等待某个条件变量;
(3) 调用singwait调用尚未发生的信号;
(4) 执行无法立即完成的I/O操作;
(5) 内存页错误等系统操作;
回收线程将释放所有在主线程终止时候未被释放的系统和进程只有;包括保存线程返回值的内存空间、堆栈、保存寄存器状态的内存空间等. 一旦线程被回收,则它的线程ID不能再被使用, 是无效的,
线程、互斥量和条件变量都有自己的特殊属性对象类型。分别是:pthread_attr_t、pthread_mutexattr_t、pthread_condattr_t。 可以将属性对象视为一个私有结构。通过特殊的函数读/写结构中的成员。
取消一个线程是异步的。当pthread_cancel返回时候,线程未必已经被取消了,可能仅仅被通知有个针对该线程的取消请求。若需要知道线程何时终止,则必须在取消置顶pthread_t之后,调用pthread_join, 因为pthread_join是阻塞的, 直到置顶pthread_t结束。
参考文献:
[1] David R.Butenhof, Programming With POSIX Threads. ISBN7-5083-1395-x, 2003
/////////// 1. kafka log文件数据 ----- strings格式形式展示
{"MetaData":{"type":"activityTarget","subType":"personalTrack","time":"2020-05-11T19:39:09.547+08:00","timeStamp":1589197149547,"DevInfo":{"ipAddress":"10.33.24.97","portNo":554,"macAddress":"ac:cb:51:19:fc:5b","channel":1,"domainName":""},"CameraPoint":[{"objId":"76","traComplete":false,"isvalid":1,"GesturePolygon":{"id":"2","JoinMsg":[{"gestureType":0,"gestureScore":0.277344,"gestureValid":1,"x":1780.417236,"y":5232.689941,"z":1445.000000,"x2d":0.842593,"y2d":0.700000},{"gestureType":1,"gestureScore":0.461914,"gestureValid":1,"x":1751.976562,"y":5600.821777,"z":1091.000000,"x2d":0.842593,"y2d":0.666667},{"gestureType":2,"gestureScore":0.723389,"gestureValid":1,"x":1765.766724,"y":5558.361816,"z":1373.000000,"x2d":0.884259,"y2d":0.691667},{"gestureType":3,"gestureScore":0.685547,"gestureValid":1,"x":1893.132935,"y":5313.480957,"z":1732.000000,"x2d":0.916667,"y2d":0.775000},{"gestureType":4,"gestureScore":0.671387,"gestureValid":1,"x":1896.650513,"y":5229.554688,"z":1426.000000,"x2d":0.837963,"y2d":0.733333},{"gestureType":5,"gestureScore":0.125488,"gestureValid":1,"x":1920.365723,"y":5117.449219,"z":1205.000000,"x2d":0.787037,"y2d":0.716667},{"gestureType":6,"gestureScore":0.545166,"gestureValid":1,"x":2137.248779,"y":5506.873047,"z":1035.000000,"x2d":0.819444,"y2d":0.758333}]},"HeadPolygon":{"Rect":{"x":0.809375,"y":0.672222,"width":0.126563,"height":0.130556},"cct":{"x":1838.563965,"y":5278.164551,"z":1750.000000},"HeadModel":{"modelNum":1,"Data":[{"poseType":2,"feaLen":0,"feaData":""}]}},"SuspList":{"suspNum":0,"Data":[]}}]}}
[root@host-10-254-254-4 kafka]# [2020-05-11 20:48:58,925] INFO [Group Metadata Manager on Broker 0]: Removed 0 expired offsets in 0 milliseconds. (kafka.coordinator.GroupMetadataManager)
[2020-05-11 20:58:58,925] INFO [Group Metadata Manager on Broker 0]: Removed 0 expired offsets in 0 milliseconds. (kafka.coordinator.GroupMetadataManager)
//2.
offset: 264541 position: 401190398 isvalid: true payloadsize: 1556 magic: 1 compresscodec: NoCompressionCodec crc: 10713469 payload: {"MetaData":{"type":"activityTarget","subType":"personalTrack","time":"2020-05-11T19:39:09.547+08:00","timeStamp":1589197149547,"DevInfo":{"ipAddress":"10.33.24.97","portNo":554,"macAddress":"ac:cb:51:19:fc:5b","channel":1,"domainName":""},"CameraPoint":[{"objId":"76","traComplete":false,"isvalid":1,"GesturePolygon":{"id":"2","JoinMsg":[{"gestureType":0,"gestureScore":0.277344,"gestureValid":1,"x":1780.417236,"y":5232.689941,"z":1445.000000,"x2d":0.842593,"y2d":0.700000},{"gestureType":1,"gestureScore":0.461914,"gestureValid":1,"x":1751.976562,"y":5600.821777,"z":1091.000000,"x2d":0.842593,"y2d":0.666667},{"gestureType":2,"gestureScore":0.723389,"gestureValid":1,"x":1765.766724,"y":5558.361816,"z":1373.000000,"x2d":0.884259,"y2d":0.691667},{"gestureType":3,"gestureScore":0.685547,"gestureValid":1,"x":1893.132935,"y":5313.480957,"z":1732.000000,"x2d":0.916667,"y2d":0.775000},{"gestureType":4,"gestureScore":0.671387,"gestureValid":1,"x":1896.650513,"y":5229.554688,"z":1426.000000,"x2d":0.837963,"y2d":0.733333},{"gestureType":5,"gestureScore":0.125488,"gestureValid":1,"x":1920.365723,"y":5117.449219,"z":1205.000000,"x2d":0.787037,"y2d":0.716667},{"gestureType":6,"gestureScore":0.545166,"gestureValid":1,"x":2137.248779,"y":5506.873047,"z":1035.000000,"x2d":0.819444,"y2d":0.758333}]},"HeadPolygon":{"Rect":{"x":0.809375,"y":0.672222,"width":0.126563,"height":0.130556},"cct":{"x":1838.563965,"y":5278.164551,"z":1750.000000},"HeadModel":{"modelNum":1,"Data":[{"poseType":2,"feaLen":0,"feaData":""}]}},"SuspList":{"suspNum":0,"Data":[]}}]}}
[root@host-10-254-254-4 SINGLE_TRACE_INFO-2]# [2020-05-11 21:18:58,925] INFO [Group Metadata Manager on Broker 0]: Removed 0 expired offsets in 0 milliseconds. (kafka.coordinator.GroupMetadataManager)
//解析json失败。
HPR_INT32 KafkaMsgTrajectory::KafkaMessageParse(StruMetaData &struMetadata)
{
HPR_INT32 iRet = LS_SERVER_ERR;
HPR_INT8* pMsg = static_cast<HPR_INT8*>(m_pReqMsg);
if(NULL == pMsg)
{
SYS_ERROR("kafka trajectory msg[%p] is null", pMsg);
return iRet;
}
do
{
string tempVar;
rapidjson::Document document;
document.Parse(pMsg);
if(document.HasParseError())
{
iRet = LS_SERVER_PARAM_ERR;
SYS_ERROR("KafkaMessageParse Parse [%s] is error", pMsg);
SYS_ERROR("parse error: (%d:%d)%s", document.GetParseError(), document.GetErrorOffset(), GetParseError_En(document.GetParseError()));
break;
}
2020-05-11 19:21:26.051 ERROR KafkaMessageParse[0055]:KafkaMessageParse Parse [{"MetaData":{"type":"activityTarget","subType":"personalTrack","time":"2020-05-11T19:21:24.126+08:00","timeStamp":1589196084126,"DevInfo":{"ipAddress":"10.33.24.63","portNo":554,"macAddress":"ac:cb:51:19:fc:47","channel":1,"domainName":""},"CameraPoint":[{"objId":"9","traComplete":false,"isvalid":1,"GesturePolygon":{"id":"1","JoinMsg":[{"gestureType":0,"gestureScore":0.788818,"gestureValid":1,"x":3778.052734,"y":3267.720703,"z":1099.000000,"x2d":0.564815,"y2d":0.500000},{"gestureType":1,"gestureScore":0.782471,"gestureValid":1,"x":3579.214355,"y":3221.026367,"z":1293.000000,"x2d":0.606481,"y2d":0.491667},{"gestureType":2,"gestureScore":0.744141,"gestureValid":1,"x":3580.788574,"y":3343.032471,"z":1710.000000,"x2d":0.629630,"y2d":0.558333},{"gestureType":3,"gestureScore":0.782471,"gestureValid":1,"x":3607.887695,"y":3601.128662,"z":1896.000000,"x2d":0.634259,"y2d":0.683333},{"gestureType":4,"gestureScore":0.799072,"gestureValid":1,"x":3754.680908,"y":3660.641602,"z":1481.000000,"x2d":0.578704,"y2d":0.650000},{"gestureType":5,"gestureScore":0.769043,"gestureValid":1,"x":3855.959473,"y":3580.994629,"z":1090.000000,"x2d":0.550926,"y2d":0.591667},{"gestureType":6,"gestureScore":0.836426,"gestureValid":1,"x":3821.448486,"y":3440.873291,"z":759.000000,"x2d":0.550926,"y2d":0.533333}]},"HeadPolygon":{"Rect":{"x":0.564062,"y":0.519444,"width":0.087500,"height":0.202778},"cct":{"x":3626.950439,"y":3583.195068,"z":1890.000000},"HeadModel":{"modelNum":0,"Data":[]}},"SuspList":{"suspNum":0,"Data":[]}},{"objId":"11","traComplete":false,"isvalid":1,"GesturePolygon":{"id":"0","JoinMsg":[{"gestureType":0,"gestureScore":0.833008,"gestureValid":1,"x":4587.995605,"y":3285.548096,"z":1057.000000,"x2d":0.435185,"y2d":0.500000},{"gestureType":1,"gestureScore":0.686768,"gestureValid":1,"x":4571.932617,"y":3303.492188,"z":1258.000000,"x2d":0.430556,"y2d":0.516667},{"gestureType":2,"gestureScore":0.687988,"gestureValid":1,"x":4622.618164,"y":3393.669678,"z":1495.000000,"x2d":0.412037,"y2d":0.558333},{"gestureType":3,"gestureScore":0.773682,"gestureValid":1,"x":4696.807617,"y":3625.930176,"z":1739.000000,"x2d":0.384259,"y2d":0.666667},{"gestureType":4,"gestureScore":0.614990,"gestureValid":1,"x":4801.964355,"y":3581.296875,"z":1532.000000,"x2d":0.375000,"y2d":0.625000},{"gestureType":5,"gestureScore":0.463379,"gestureValid":1,"x":4672.041992,"y":3558.843262,"z":1746.000000,"x2d":0.388889,"y2d":0.641667},{"gestureType":6,"gestureScore":0.360107,"gestureValid":1,"x":4612.968750,"y":3579.637207,"z":1729.000000,"x2d":0.402778,"y2d":0.650000}]},"HeadPolygon":{"Rect":{"x":0.367188,"y":0.522222,"width":0.071875,"height":0.175000},"cct":{"x":4736.142578,"y":3530.066895,"z":1750.000000},"HeadModel":{"modelNum":0,"Data":[]}},"SuspList":{"suspNum":0,"Data":[]}}]}}] is error
[root@host-10-254-254-1 CenterController]#