【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

之前我们也谈到了线程创建,基本上简单的系统就可以跑起来了,但是还没有到多线程运行的地步。所以,我们下面试图所要做的工作就是创建更多的线程,让更多的线程运行起来。为了做好这一点,首先我们需要对task_init重新修整一下,

void task_init(int index, UINT32 data[], int size, void (*func)())
{
UINT32 unit = size;
memset((void*)data, 0, size * sizeof(UINT32));
data[unit -1] = (UINT32) func;
data[unit -2] = 0;
data[unit -3] = 0;
data[unit -4] = 0;
data[unit -5] = 0;
data[unit -6] = 0;
data[unit -7] = 0;
data[unit -8] = 0;
data[unit -9] = 0;
data[unit -10] = (UINT32) &data[unit - 9];
new[index] = (UINT32) &data[unit -10];
}

这是一个创建线程的函数,有堆栈、大小、函数入口。那么,我们的函数什么时候创建呢,其实就是在系统的开始位置就可以,

void set_all_task()
{
int index;
for(index = 0; index < THREAD_MAX_NUMBER; index ++)
task_init(index, task_stack[index], STACK_LENGTH, hello);
}

既然任务创建没有问题,那么下面就会涉及到简单轮转的问题。其实我们的方法特别简单,就是根据current_thread_id叠加,每一个thread都有自己的运转机会。代码如下所示,

void signal_handler(int m)
{
current_thread_id = current_thread_id % THREAD_MAX_NUMBER;
if(0 == quit[current_thread_id])
{
swap(&old, &new[current_thread_id]);
}
printf("count = %d in main!\n\n",  count ++);
current_thread_id ++;
}

当然,为了要实现真正的多线程运行,我们还要保证线程始终在运行。要达到这一点也不是很复杂,只需要把子函数设计为while(1)即可,

void hello()
{
while(1) {
printf("id = %i, count = %d in thread!\n",current_thread_id,  count ++);
swap(&new[current_thread_id], &old);
printf("id = %i, count = %d in thread!\n",current_thread_id,  count ++);
swap(&new[current_thread_id], &old);
}
}

基本上要做到以上几点就可以实现了,最后给出完整的代码,大家可以在linux系统好好试试这个代码。

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <signal.h>
#include <assert.h>
#include <sys/time.h>
#define UINT32 unsigned   int
#define STACK_LENGTH      512
#define THREAD_MAX_NUMBER 10
struct itimerval oldtv;
UINT32 old   = 0;
UINT32 count = 0;
UINT32 task_stack[THREAD_MAX_NUMBER][STACK_LENGTH] = {0};
UINT32 new[THREAD_MAX_NUMBER]  = {0};
UINT32 quit[THREAD_MAX_NUMBER] = {0};
UINT32 current_thread_id = 0;
void set_timer()
{
struct itimerval itv;
itv.it_interval.tv_sec = 1;
itv.it_interval.tv_usec = 0;
itv.it_value.tv_sec = 1;
itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, &oldtv);
}
void swap(UINT32* prev, UINT32* next)
{
__asm("push %%eax\n\t"
"push %%ebx\n\t"
"push %%ecx\n\t"
"push %%edx\n\t"
"push %%esi\n\t"
"push %%edi\n\t"
"push %%ebp\n\t"
"push %%esp\n\t"
"lea 0x8(%%ebp), %%eax\n\t"
"mov (%%eax), %%eax\n\t"
"mov %%esp, (%%eax)\n\t"
"lea 0xc(%%ebp), %%eax\n\t"
"mov (%%eax), %%eax\n\t"
"mov (%%eax), %%esp\n\t"
"pop %%esp\n\t"
"pop %%ebp\n\t"
"pop %%edi\n\t"
"pop %%esi\n\t"
"pop %%edx\n\t"
"pop %%ecx\n\t"
"pop %%ebx\n\t"
"pop %%eax\n\t"
::);
}
void hello()
{
while(1) {
printf("id = %i, count = %d in thread!\n",current_thread_id,  count ++);
swap(&new[current_thread_id], &old);
printf("id = %i, count = %d in thread!\n",current_thread_id,  count ++);
swap(&new[current_thread_id], &old);
}
}
void task_init(int index, UINT32 data[], int size, void (*func)())
{
UINT32 unit = size;
memset((void*)data, 0, size * sizeof(UINT32));
data[unit -1] = (UINT32) func;
data[unit -2] = 0;
data[unit -3] = 0;
data[unit -4] = 0;
data[unit -5] = 0;
data[unit -6] = 0;
data[unit -7] = 0;
data[unit -8] = 0;
data[unit -9] = 0;
data[unit -10] = (UINT32) &data[unit - 9];
new[index] = (UINT32) &data[unit -10];
}
void signal_handler(int m)
{
current_thread_id = current_thread_id % THREAD_MAX_NUMBER;
if(0 == quit[current_thread_id])
{
swap(&old, &new[current_thread_id]);
}
printf("count = %d in main!\n\n",  count ++);
current_thread_id ++;
}
void set_all_task()
{
int index;
for(index = 0; index < THREAD_MAX_NUMBER; index ++)
task_init(index, task_stack[index], STACK_LENGTH, hello);
}
int main()
{
char val;
set_all_task();
set_timer();
signal(SIGALRM, signal_handler);
while(1)
{
scanf("%c", &val);
}
exit(0);
return 1;
}

嵌入式操作系统内核原理和开发(多线程轮转)相关推荐

  1. 嵌入式操作系统内核原理和开发

    嵌入式操作系统内核原理和开发(开篇) 操作系统是很多人每天必须打交道的东西,因为在你打开电脑的一刹那,随着bios自检结束,你的windows系统已经开始运行了.如果问大家操作系统是什么?可能有的人会 ...

  2. 嵌入式操作系统内核原理和开发(总结篇)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 很多朋友都喜欢嵌入式操作系统的内容,但是如何实现和仿真这样一个系统一直是困扰我们的难题.现在郑 ...

  3. 嵌入式操作系统内核原理和开发(地址空间)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 不管是什么样的嵌入式cpu,它必然有自己的访问地址空间.至于这个具体的访问空间是什么,那cpu ...

  4. 嵌入式操作系统内核原理和开发(信号量)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 之前因为工作的原因,操作系统这块一直没有继续写下去.一方面是自己没有这方面的经历,另外一方面就 ...

  5. 嵌入式操作系统内核原理和开发(头文件调整)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 很长一段时间,我个人对头文件的功能了解得不是很明白.虽然在平时的开发中,对于头文件也没有犯过什 ...

  6. 嵌入式操作系统内核原理和开发(任务创建和堆栈溢出检查)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 虽然写操作系统的博客要比写普通的技术点要麻烦一些,但是心中还是挺开心的.一方面,通过几行代码就 ...

  7. 嵌入式操作系统内核原理和开发(基础)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 在编写我们的操作系统之前,我们需要明确一些事情.比如说,这个系统的运行环境是什么?怎么编译?基 ...

  8. 嵌入式操作系统内核原理和开发(cpu的那些事)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] cpu是数字处理系统中的一个重要环节.在我看来,单片机.微处理器.dsp都可以称作是cpu,只 ...

  9. 嵌入式操作系统内核原理和开发(开篇)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 操作系统是很多人每天必须打交道的东西,因为在你打开电脑的一刹那,随着bios自检结束,你的wi ...

最新文章

  1. (转)解决ubuntu下拼音输入法出错的问题
  2. keil 多文件组织方法
  3. Tomcat性能调优-JVM监控与调优
  4. 【机器学习】从一个风控案例讲起-古老而经典的朴素贝叶斯
  5. ICCV 2019 | 从多视角RGB图像生成三维网格模型Pixel2Mesh++
  6. 看完Andoird9.0 Pie的隐藏特性,我买了SSL证书
  7. 如何看待雅虎套现760亿美元从阿里巴巴退出?
  8. 2020牛客国庆集训派对day4 Emergency Evacuation
  9. 151205 财务管理原理作业(笔试题型)
  10. POJ 3660 Cow Contest【传递闭包】
  11. r语言实现岭回归_数据分析中常见的七种回归分析以及R语言实现(五)
  12. freemarker 数组转字符串_TypeScript 实战算法系列(一):实现数组栈与对象栈
  13. 串口如何接收数据_原创分享 | S71200通过串口服务器读取MODBUS RTU设备
  14. 国行ps4服务器维护,不能登录其地区的PSN代表什么
  15. screwing up
  16. Gilbert Strang的线性代数课程笔记-第一课
  17. 2022茶艺师(中级)考试题及模拟考试
  18. 测试苹果授权登录Sign in with apple时,提示“未完成注册”处理经验分享
  19. BF算法及KMP算法
  20. 支付机构违规已成常态 盛付通再次被央行处罚

热门文章

  1. 笔记:AIX系统/var/adm/wtmp大文件处理
  2. 大数据支撑健康医疗服务落地
  3. 03-树3 Tree Traversals Again
  4. 【转】什么是磁珠(Ferrite Bead 即 FB)
  5. 小白学习vuex的超级全面版本
  6. linux查看CPU高速缓存(cache)信息
  7. 让计算机启动更快的十五招
  8. c#使用zlib.net压缩解压byte数组
  9. 大数据_Flink_Java版_数据处理_窗口起始点和偏移量---Flink工作笔记0058
  10. 投标工作笔记001---竞标和围标