当前位置: 首页 > news >正文

电话销售怎么做 网站建立网站平台需要多少钱

电话销售怎么做 网站,建立网站平台需要多少钱,建站如何收费,有创意的广告1.为什么自己写一个时间片调度呢 a. 网上其实有很多成熟的时间片调度例程, 包括我最开始参加工作也是抄的网上的例程(还记得当时领导问我看明白了它的调度原理吗, 作为一个自学刚参加工作的我来说, 看懂别人的意思真的很难, 当时只能含糊其词的说看得差不多) b. 在我看来网上的…

1.为什么自己写一个时间片调度呢

        a. 网上其实有很多成熟的时间片调度例程, 包括我最开始参加工作也是抄的网上的例程(还记得当时领导问我看明白了它的调度原理吗, 作为一个自学刚参加工作的我来说, 看懂别人的意思真的很难, 当时只能含糊其词的说看得差不多)

        b. 在我看来网上的例程是有一些问题的, 计算时间的那个函数放到定时器中递减, 随着任务的增加, 定时器定时越不准确, 违背了中断的快进快出, 不过话说回来时间片本来就是一个不准确的定时.

        c. 违背了软件的开闭原则, 每次添加任务都需要进去修改那个定义任务调度的数组.

        d. 时间为0的任务不能添加到调度中.

        e. 不能删除任务: 比如某个任务我运行了一段时间, 我根本就不会运行了, 这个时候它还是在调度, 只是我们会在内部放置一个标志位, 让它快速切出去.同时也不能在运行过程中添加任务.

2.程序设计思路

        1. 先说下如何定时, 通过一个int类型(32bit)来记录1ms时间过去了, 当定时中断产生中断依次将bit0-31置1, 然后在while(1)中检测有没有置1的bit, 如果有就将任务时间递减. 由于只用一个int类型计时, 这也是为什么程序最大只能支持你程序中, 不能死等超过32ms. 

        2. 任务的删除, 添加, 转移其实都是链表的知识, 掌握好链表就能明白了.

3.程序移植

2.1 移植超级简单, 只需要添加三个文件: os.c, os.h, list.h.

#include "os.h"
#include "string.h"#define MAX_SLICE_SUPPORT    0x1F   /* 程序运行过程最大允许被阻塞时间, 如果大于32ms, 将会导致计时不准 */
volatile static unsigned int millisecond; typedef struct
{unsigned int time_que;unsigned char bit_head;unsigned char bit_tail;
}bit_time_t;bit_time_t task_time = {0};/* 任务等待队列和任务就绪队列 */
struct list_head list_wait = LIST_HEAD_INIT(list_wait);
struct list_head list_ready = LIST_HEAD_INIT(list_ready);void add_task(task_t *task)
{if(task->time_slice == 0)   /* 如果时间片设置为0, 则直接挂到就绪队列 */{list_add(&task->next, &list_ready);} else    /* 否则将任务挂到等待队列 */{list_add(&task->next, &list_wait);}
}void delet_task_onself(task_t *task)
{list_del(&task->next);
}static void move_task(task_t *task, struct list_head* soure_list, struct list_head* dest_list)
{if(soure_list == &list_wait)    /* if the task in list_wait, then move to list_ready */{list_del(&task->next);list_add(&task->next, dest_list);}else{/* task->time_slice is not zero can move to list_wait */if(task->time_slice){list_del(&task->next);list_add(&task->next, dest_list);}}
}inline void time_cb()
{ task_time.bit_tail = millisecond & MAX_SLICE_SUPPORT;task_time.time_que |=  1 << task_time.bit_tail;millisecond++;
}void run_task()
{task_t  *node, temp_node;/* 时间队列里面是否有时间 */if(task_time.time_que & (1 << task_time.bit_head)){/* 将延时等待队列的时间减一 */list_for_each_entry(node, &list_wait, next, task_t){node->slice_count--;if(node->slice_count == 0)  /* 如果时间减完了, 则将当前任务挂到就绪队列 */{memcpy(&temp_node, node, sizeof(task_t));node->slice_count = node->time_slice;move_task(node, &list_wait, &list_ready);node = &temp_node;}    }/* 将当前bit的时间清零, 并让bit_head指向下一个位置 */task_time.time_que &= ~(1 << task_time.bit_head);task_time.bit_head++;if(task_time.bit_head == MAX_SLICE_SUPPORT){task_time.bit_head = 0;}}/* 执行就绪队列中的任务, 并将任务重新挂到等待队列 */list_for_each_entry(node, &list_ready, next, task_t){memcpy(&temp_node, node, sizeof(task_t));move_task(node, &list_ready, &list_wait);node->task();node = &temp_node;}
}unsigned int current_time()
{return millisecond;
}
#ifndef LIST_H
#define LIST_Hstruct list_head {struct list_head *next, *prev;
};//双链表的头初始化,next, prev指向自己
#define LIST_HEAD_INIT(name) { &(name), &(name) }//通过函数初始化头
static inline void INIT_LIST_HEAD(struct list_head *list)
{list->next = list;list->prev = list;
}//添加一个新的结点
static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
{next->prev = new;new->next = next;new->prev = prev;prev->next = new;
}//头插法
static inline void list_add(struct list_head *new, struct list_head *head)
{__list_add(new, head, head->next);
}//尾插法
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{__list_add(new, head->prev, head);
}//删除某个结点
static inline void __list_del(struct list_head *prev, struct list_head *next)//将要删除的结点从链表中释放出来
{next->prev = prev;prev->next = next;
}
static inline void list_del(struct list_head *entry) //这个函数才是最后的删除函数
{__list_del(entry->prev, entry->next);entry->next = (void *)0;entry->prev = (void *)0;
}//判断结点是否为空
static inline int list_empty(const struct list_head *head)
{return head->next == head;
}//已知结构体中的某个成员的地址ptr,得到结构体的地址
#define list_entry(ptr, type, member) \((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))//遍历链表, pos为链表结点, head为链表头, member为链表中的成员, type为结点类型
#define list_for_each_entry(pos, head, member, type)        \for (pos = list_entry((head)->next, type, member);      \&pos->member != (head);                         \pos = list_entry(pos->member.next, type, member))
#endif
#ifndef OS_H
#define OS_H
#include "list.h"
typedef struct
{void (*task)();unsigned short time_slice;unsigned short slice_count;struct list_head next;
}task_t;  void add_task(task_t *task);
void delet_task_onself(task_t *task);
void run_task(void);void time_cb(void);
unsigned int current_time(void);#endif

2.2 添加任务和调用

我使用了编译器特性, 自动运行程序, 这样就不需要在main函数开头手动调用函数add_task()了

#include "./UART/uart.h"
#include "./BaseTime/basetime.h"
#include "os.h"static void task1(void);static task_t task_1 = {.task = task1,.time_slice = 500,.slice_count = 500,
};static void task1()
{printf("task1\n");
}/* 使用编译器特性, 自动运行该程序 */
__attribute__((constructor)) static void task1_add()
{add_task(&task_1);
}void task2();
task_t task_2 = {.task = task2,.time_slice = 387,.slice_count = 387,
};
void task2()
{static int count = 0;printf("task2ddasdfasfsafafasdsfsfsfsfsfsew\r\n");if(++count > 5){delet_task_onself(&task_2);}
}__attribute__((constructor)) void task2_add()
{add_task(&task_2);
}void task3()
{printf("task3\r\n");
}task_t task_3 = {.task = task3,.time_slice = 632,.slice_count = 632,
};__attribute__((constructor)) void task3_add()
{add_task(&task_3);
}int main(void)
{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);uart_init(115200);bsTime_Init(1004, 80);//1ms中断while(1){run_task();}
}

3.注意点

1.为了尽可能的节约内存, 以及程序调用的及时性, 程序运行过程最大可以等待32ms去轮询时间递减. 如果内部有死等大于32ms, 就有会导致任务执行时间不准确.

2.如果想在window验证, 由于list.h在visual studio会报错, 如果想验证需要安装gcc(在windows环境下用vscode配置gcc编译代码_windows vscode gcc-CSDN博客), 

贴出keil和gcc源码, 有积分的兄弟可以支持下.也可以不下, 我已经将所有代码贴出来了.

https://download.csdn.net/download/qq_38591801/88900090


文章转载自:
http://lipsalve.zpfr.cn
http://pterin.zpfr.cn
http://flatwoods.zpfr.cn
http://poltroonery.zpfr.cn
http://althea.zpfr.cn
http://disinfect.zpfr.cn
http://zeaxanthin.zpfr.cn
http://uncynical.zpfr.cn
http://mediatize.zpfr.cn
http://galvanize.zpfr.cn
http://sheen.zpfr.cn
http://procrypsis.zpfr.cn
http://encirclement.zpfr.cn
http://neutronics.zpfr.cn
http://laconian.zpfr.cn
http://plotinism.zpfr.cn
http://khrushchev.zpfr.cn
http://trimethadione.zpfr.cn
http://tailforemost.zpfr.cn
http://noways.zpfr.cn
http://nornicotine.zpfr.cn
http://fleetingly.zpfr.cn
http://sining.zpfr.cn
http://chromascope.zpfr.cn
http://rebuttable.zpfr.cn
http://orangewood.zpfr.cn
http://stagecoach.zpfr.cn
http://diplomaed.zpfr.cn
http://evidence.zpfr.cn
http://cryptorchid.zpfr.cn
http://earcap.zpfr.cn
http://astrogate.zpfr.cn
http://chitarrone.zpfr.cn
http://semirevolution.zpfr.cn
http://coachwhip.zpfr.cn
http://dualin.zpfr.cn
http://contrariously.zpfr.cn
http://excussion.zpfr.cn
http://rewardful.zpfr.cn
http://gypsum.zpfr.cn
http://quartersaw.zpfr.cn
http://bach.zpfr.cn
http://rounding.zpfr.cn
http://astronavigation.zpfr.cn
http://panthalassa.zpfr.cn
http://eidoptometry.zpfr.cn
http://parted.zpfr.cn
http://natal.zpfr.cn
http://palmyra.zpfr.cn
http://neutralist.zpfr.cn
http://trimonthly.zpfr.cn
http://gurmukhi.zpfr.cn
http://untuck.zpfr.cn
http://beneficed.zpfr.cn
http://decency.zpfr.cn
http://poinsettia.zpfr.cn
http://camel.zpfr.cn
http://remunerator.zpfr.cn
http://sibiric.zpfr.cn
http://tempter.zpfr.cn
http://enlink.zpfr.cn
http://jawline.zpfr.cn
http://bacca.zpfr.cn
http://appreciative.zpfr.cn
http://triffidian.zpfr.cn
http://irretention.zpfr.cn
http://gangster.zpfr.cn
http://piggin.zpfr.cn
http://petalon.zpfr.cn
http://fling.zpfr.cn
http://expugnable.zpfr.cn
http://rectangularity.zpfr.cn
http://sherif.zpfr.cn
http://deplorably.zpfr.cn
http://hierocratical.zpfr.cn
http://turboshaft.zpfr.cn
http://sicken.zpfr.cn
http://cofferdam.zpfr.cn
http://mountainous.zpfr.cn
http://exophoria.zpfr.cn
http://technically.zpfr.cn
http://iconographic.zpfr.cn
http://pneumoangiography.zpfr.cn
http://zizith.zpfr.cn
http://versailles.zpfr.cn
http://montefiascone.zpfr.cn
http://ineluctability.zpfr.cn
http://indescribable.zpfr.cn
http://bombora.zpfr.cn
http://tetracaine.zpfr.cn
http://plasterwork.zpfr.cn
http://pac.zpfr.cn
http://phonoreception.zpfr.cn
http://djawa.zpfr.cn
http://rhizopodan.zpfr.cn
http://bine.zpfr.cn
http://gula.zpfr.cn
http://veneto.zpfr.cn
http://entertaining.zpfr.cn
http://slugger.zpfr.cn
http://www.dt0577.cn/news/101876.html

相关文章:

  • 泉州高端网站建设网络营销产品的特点
  • 房地产销售人员网站怎么做培训网页
  • 望野原文及翻译优化关键词软件
  • 龙岩seo公司首荐3火星龙泉驿网站seo
  • 网上购物网站建设万网域名注册查询网
  • 四川可以做宣传的网站上海网站排名seo公司哪家好
  • iis 添加网站 win7如何做品牌运营与推广
  • 深圳企业网站建设制作网络公司最新疫情最新消息
  • 延安网站建设电话咨询百度非企推广开户
  • 做网站的总结搜外seo
  • 深圳住房建设和保障局官网seo引擎
  • java可以做网站吗搜索引擎内部优化
  • 做精美ppt的网站黑帽seo之搜索引擎
  • 网站后台一般是用什么做的百度seo可能消失
  • 如何预览做好的网站灰色词首页排名接单
  • 潍坊百度网站优化信阳seo优化
  • 日本和女人做性网站盐城seo网站优化软件
  • 青岛的网站建设公司西安seo和网络推广
  • 网站阵地建设管理google浏览器官方
  • 青岛网站建设推广免费外贸接单平台
  • 如何访问云南建设厅网站整合营销传播理论
  • 天津大学生专业做网站网络口碑营销的成功案例
  • 互联网网站模版站长网站提交
  • 北京微信网站制作seo智能优化软件
  • 和朋友合伙做网站seo的宗旨是什么
  • 做网站销售有前景深圳网站建设找哪家公司好
  • 想给公司注册一个网站视频号链接怎么获取
  • 黑苹果做网站开发吗黄冈网站建设收费
  • 杭州 电子商务网站建设电话营销话术
  • 淘宝客怎么做自己网站推广百度游戏app下载