linux while 时间,FALinux系统的实现——rtlinux编程(四):周期线程

前面三节中的线程都是单次线程,即只执行一次便注销。在实时系统中,通常包括周期线程(在文章中用任务表述)和非周期线程(单次线程)。为了实现周期线程,RTLinux采用while循环的方式实现,即while一次表示该线程的一次执行。

从表面意义上来看,周期线程应该包括一个周期属性,表示该线程多长时间执行一次(从程序角度上来说也叫循环一次)。现在,我们从一个实际的例子当中来看周期线程是如何创建和工作的。

#include

#include

#include

#include

#include

MODULE_LICENSE("GPL v2");

MODULE_AUTHOR("der.herr@hofr.at");

MODULE_DESCRIPTION("pure posix periodic thread");

#define US_PER_SECOND 1000 * 1000

#define NS_PER_SECOND 1000 * 1000 * 1000

pthread_t thread1;

void *start_routine(void *arg)

{

struct sched_param p;

int i=0;

p . sched_priority = 1;

pthread_setschedparam

(pthread_self(), SCHED_FIFO, &p);

pthread_make_periodic_np

(pthread_self(), gethrtime(), (hrtime_t)5 * NS_PER_SECOND);

while(1)

{

i++;

rtl_printf("I

am the period thread, I have executed %d times\n", i);

mdelay(1000);

pthread_wait_np();

}

}

int init_module(void) {

int ret;

ret = pthread_create

(&thread1, NULL, start_routine,(void *) 1);

if (ret == EAGAIN)

{

rtl_printf("Create

thread1 failed.\n");

return -1;

}

return 0;

}

void cleanup_module(void) {

pthread_delete_np(thread1);

printk("thread

terminated\n");

}

该程序中,init_module创建一个线程thread1,在thread1的执行函数start_routine中,调用pthread_setschedparam()函数设置该线程的优先级。该函数具有三个参数:1.线程号,2.调度策略3.调度参数(只有优先级)。其中调度策略在实时程序中是无用的。Pthread_self()返回当前执行线程的线程号。我想rtlinux的开发者之所以这样设计,是为了那些习惯于编写linux程序的人。我们通过该函数设置thread1的优先级为1,然后调用函数pthread_make_periodic_np。该函数也同样包括三个参数:1.线程号;2.周期开始时间(绝对开始时间);3.周期大小。后两个参数的数值类型为hrtime_t,该类型等价于long long。程序中,第二个参数gethrtime()返回当前时间,时间格式为hrtime_t。值得注意的第三个参数,如果我们将第三个参数改为5 * NS_PER_SECOND,编译过程中会出现如下警告:

warning: integer overflow in expression。因为5会默认为int类型,当乘以NS_PER_SECOND后,该值超出了int的范畴,为此,很有必要对5进行强制类型转换。在这细心的读者会发现NS_PER_SECOND在定义的时候采用#define NS_PER_SECOND 1000 * 1000 * 1000,而不是#define NS_PER_SECOND 1000000000。其原因是前者能够让人很清楚的知道NS_PER_SECOND是1亿,而后者却要麻烦人去耐心的查0的个数,稍微不细心,就会少写或者多写1个0。

经过pthread_make_periodic_np函数后,rtlinux内核已经把thread1标记为周期线程了,其标志方法就是设置thread1的resume_time值.,该值的具体作用在后面我们会做具体介绍。该函数执行完毕后,thread1会继续执行。这跟某些资料的阐述是不一样的。有些资料说该函数执行完毕后,线程会挂起,直到到达其开始时间,也即是第二个参数,这种说法是不对的。即使当开始时间大于当前时间,该函数也不会挂起该线程。具体原因我们在后面用专门的一节来解释。

While循环中,我们使用i作为计数来显示周期线程的执行次数。Thread1每次执行都会忙等待1秒钟,然后执行pthread_wait_np。这个函数表示将当前线程挂起,直到下次周期时间的到来。下次到达时间也在该函数中被设置,设置的代码是self->resume_time+=self->period.

该程序的运行结果如下所示:

I am the period thread, I have executed 1 times

I am the period thread, I have executed 2 times

I am the period thread, I have executed 3 times

I am the period thread, I have executed 4 times

thread terminated

编写周期线程应该注意以下几点:

1.pthread_make_periodic_np中第三个参数进行必要的强制类型转换:(hrtime_t)。

2.线程的周期不能小于该线程的执行时间,否则系统会一直执行实时程序,而无时间来响应非实时程序。

3.While循环体中必须包括pthread_wait_np函数,否则出现与2一样的情况。

4.周期线程是个死循环,如果想终止该线程,则需要在shell中通过rmmod命令卸载该实时模块。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值