前段时间有个需求是向S端发送消息,如果在20S之内没有收到S端的回执,就要对发送的消息进行超时处理。在一个线程中去处理超时消息,创建一个单链表,在发送消息的同时,将该消息体加到链表中,在线程中一直对这个链表进行遍历,查看时间是否大于等于20,如果大于等于20,就告诉用户消息超时,接着从链表中删除该消息,或者这个数据的标志位为1,也从链表中删除该消息。如果过了20S收到消息回执,则将该消息的的标志位置为1。
pthread_attr_t timeOutAttr;
pthread_t timeOut_mythread;
- 初始化链表,并开启线程
// 初始化链表
linklistInit(&head);
// 开启超时定时器 超时提醒用户重传
pthread_attr_init(&timeOutAttr);
pthread_attr_setdetachstate(&timeOutAttr, PTHREAD_CREATE_DETACHED);
if ((pthread_create(&timeOut_mythread, &timeOutAttr, thread_timeOut_function(), NULL)) < 0) {
printf("create thread_timeOut error \n");
}
- 超时处理
void *thread_timeOut_function() {
while (1) {
//遍历链表,查看时间是否大于等于20
LinkNode *currentNode = head;
int time = 0;
while (currentNode != NULL) {
linkData linkMessageData;
memset(&linkMessageData, 0, sizeof(linkData));
time = currentNode->linkMessageData.time;
if (time >= 20) {
// 返回给用户,数据超时,需要用户重新去发送数据
// 从链表中删除该数据
linklistErase(&head, currentNode);
} else if (currentNode->linkMessageData.flag == 1) {
// 从链表中删除该数据
linklistErase(&head, currentNode);
} else {
sleep(1);
currentNode->linkMessageData.time = time + 1;
}
currentNode = currentNode->next;
}
}
}
- 回执消息处理
//判断是否是超时的消息
LinkNode *currentNode = head;
while (currentNode != NULL) {
if (strcmp(currentNode->linkMessageData.messageMid, receiveMessageRsp->mid) == 0) {
// 修改标志位为1,表示这条消息已经收到回执
changeLinklist_flag(&head, currentNode, 1);
break;
}
currentNode = currentNode->next;
}
- 链表处理 linklist.h
typedef struct linkData {
BYTE *messageMid;
int time;
int flag;
}linkData;
typedef struct LinkNode {
linkData linkMessageData; // 数据域
struct LinkNode *next; // 指针域
}LinkNode;
// 初始化
void linklistInit(LinkNode **head);
// 节点销毁
void DestroyNode(LinkNode *node);
// 打印链表
void linklistPrint(LinkNode *head);
// 逆序打印链表
void linklistReversePrint(LinkNode *head);
// 在链表末尾插入
LinkNode *linklistPushBack(LinkNode **head, linkData linkMessageData);
// 在链表末尾删除
void linklistPopBack(LinkNode **head);
// 在链表头部插入
void linklistPushFront(LinkNode **head, linkData linkMessageData);
// 在链表头部删除
void linklistPopFront(LinkNode **head);
// 修改链表中的指定元素值
void changeLinklist_flag(LinkNode **head, LinkNode *pos, int flag);
// 删除指定元素(遍历)
void linklistErase(LinkNode **head, LinkNode *pos);
// 删除指定元素(不遍历)
void linklistErase2(LinkNode **head, LinkNode *pos);
// 判断链表是否为空,空则返回0否则返回1
int linklistEmpty(LinkNode *head);
// 链表元素的个数
size_t linklistSize(LinkNode *head);
- 链表处理 linklist.c
// 初始化函数
void linklistInit(LinkNode **head) {
*head = NULL;
}
// 创建新节点函数
LinkNode *CreateNode(linkData linkMessageData) {
// 为新节点申请空间
LinkNode *new_node = (LinkNode *)malloc(sizeof(LinkNode));
// 给新节点赋值
new_node->linkMessageData = linkMessageData;
// 将新节点的next指向null
new_node->next = NULL;
return new_node;
}
// 销毁一个节点
void DestroyNode(LinkNode *node) {
free(node->linkMessageData.messageMid);
free(node);
}
// 顺序打印链表
void linklistPrint(LinkNode *head) {
if (head == NULL) {
// 空链表无需打印
return;
}
LinkNode *currentNode = head;
while (currentNode != NULL) {
printf("%d | %p\n",currentNode->linkMessageData.time,currentNode);
// 让currentNode等于currentNode->next
currentNode = currentNode->next;
}
}
// 逆序打印链表
void linklistReversePrint(LinkNode *head) {
if (head == NULL) {
return;
}
linklistReversePrint(head->next);
printf("%s | %p\n",head->linkMessageData.messageMid,head);
}
// 尾插函数
LinkNode *linklistPushBack(LinkNode **head, linkData linkMessageData) {
// 非法输入
if (head == NULL) {
return NULL;
}
// 空链表
if (*head == NULL) {
*head = CreateNode(linkMessageData);
return NULL;
} else {
LinkNode *currentNode = *head;
// 遍历元素,让currentNode指向最后一个元素
while (currentNode->next != NULL) {
currentNode = currentNode->next;
}
LinkNode *new_code = CreateNode(linkMessageData);
currentNode->next = new_code;
return new_code;
}
}
// 尾删函数
void linklistPopBack(LinkNode **head) {
// 非法输入
if (head == NULL) {
return;
}
// 空链表没有可删除的元素
if (*head == NULL) {
return;
}
// 只有一个元素
if ((*head)->next == NULL) {
DestroyNode(*head);
// 将头结点置空
*head = NULL;
return;
} else {
LinkNode *currentNode = *head;
// 遍历链表,使currentNode指向倒数第二个元素
while (currentNode->next->next != NULL) {
currentNode = currentNode->next;
}
// 创建指针指向最后一个元素,也就是需要删除的元素
LinkNode *to_delete_node = currentNode->next;
DestroyNode(to_delete_node);
// 将倒数第二个元素的next指向空
currentNode->next = NULL;
}
return;
}
// 头插函数
void linklistPushFront(LinkNode **head, linkData linkMessageData) {
// 非法输入
if (head == NULL) {
return;
}
// 空链表
if (*head == NULL) {
*head = CreateNode(linkMessageData);
return;
} else {
// 创建一个新的指针指向头结点
LinkNode *new_node = *head;
// 创建一个新的头结点
*head = CreateNode(linkMessageData);
// 将新的头结点的next指向旧的头结点
(*head)->next = new_node;
}
return;
}
// 头删函数
void linklistPopFront(LinkNode **head) {
// 非法输入
if (head == NULL) {
return;
}
// 空链表
if (*head == NULL) {
return;
} else {
// 创建一个新的指针指向头结点
LinkNode *new_node = (*head)->next;
// 将头结点的next指向NULL
(*head)->next = NULL;
// 删除该头结点
DestroyNode(*head);
// 将第二个元素设置为新的头结点
*head = new_node;
}
return;
}
// 修改链表中的指定元素值
void changeLinklist_flag(LinkNode **head, LinkNode *pos, int flag) {
// 非法输入
if (head == NULL) {
return;
}
// 空链表
if (*head == NULL) {
return;
}
// 如果pos位置为空
if (pos == NULL) {
return;
}
LinkNode *currentNode = *head;
if (pos != *head) {
while (currentNode->next != pos) {
currentNode = currentNode->next;
}
}
pos->linkMessageData.flag = flag;
// free(currentNode);
}
// 删除指定元素(遍历)
void linklistErase(LinkNode **head, LinkNode *pos) {
// 非法输入
if (head == NULL) {
return;
}
// 空链表
if (*head == NULL) {
return;
}
// 如果pos位置为空
if (pos == NULL) {
return;
}
// 如果pos为头结点的位置
if (pos == *head) {
linklistPopFront(head);
return;
} else {
// 创建新的指针指向头结点
LinkNode *currentNode = *head;
while (currentNode->next != pos) {
currentNode = currentNode->next;
}
currentNode->next = pos->next;
DestroyNode(pos);
}
}
// 删除指定元素(不遍历)
void linklistErase2(LinkNode **head, LinkNode *pos) {
if (head == NULL) {
return;
}
// 空链表
if (*head == NULL) {
return;
}
// 如果pos位置为空
if (pos == NULL) {
return;
}
// 如果pos为头结点的位置
if (pos == *head) {
linklistPopFront(head);
return;
} else {
LinkNode *to_delete_Node = pos->next;
pos->linkMessageData = to_delete_Node->linkMessageData;
pos->next = to_delete_Node->next;
DestroyNode(to_delete_Node);
}
}
// 判断链表是否为空链表
int linklistEmpty(LinkNode *head) {
return head == NULL ? 0 : 1;
}
// 链表元素的个数,返回元素个数
size_t linklistSize(LinkNode *head) {
// 空链表返回0
if (head == NULL) {
return 0;
}
size_t count = 0;
LinkNode *currentNode = head;
// 遍历链表
for (;currentNode != NULL;currentNode = currentNode->next) {
count++;
}
return count;
}