Linux编程-线程优先级的设定
 2016.04.04    |      应用编程    |     AilsonJack    |     暂无评论    |     2066 views
广告位C招租:1
By: Ailson Jack
Date: 2016-04-04
个人博客: http://www.only2fire.com/
<p style="text-indent: 2em;">最近在学习Linux的编程,这里在博客中记录一下学习的过程。<br/></p><p style="text-indent: 2em;">对于线程的优先级设定,在网上也看了不少的文章,大多数都只介绍了一个线程,<span style="color: rgb(255, 0, 0);">关键是介绍的例程,设置的线程优先级都不起作用</span>。由于之前接触的Linux编程知识比较少,这个问题困扰了我一晚上。于是接着在网上看资料,终于能够使线程的优先级设置有效。</p><p class="artical_littlestyle1">1、相关知识介绍</p><p style="text-indent: 2em;">首先总结一下,线程优先级设置的条件:<br/></p><p style="text-indent: 2em;">a、线程的调度策略必须为:SCHED_RR或SCHED_FIFO;<br/></p><p style="text-indent: 2em;">b、线程的继承策略必须为:PTHREAD_EXPLICIT_SCHED<br/></p><p style="text-indent: 2em;">对于继承策略,这里举个简单的例子:<br/></p><p style="text-indent: 2em;">如果线程A创建了线程B,则线程B的调度策略与线程A的调度策略和线程B的继承策略有关的:<br/></p><p style="text-indent: 2em;">如果线程B继承策略为PTHREAD_INHERIT_SCHED,则线程B的调度策略与线程A相同,线程B的优先级也与线程A相同,但是线程B不能够自己修改调度策略与优先级(个人理解,不对请指教);<br/></p><p style="text-indent: 2em;">如果线程B继承策略为PTHREAD_EXPLICIT_SCHED,则线程B的调度策略由线程属性attr决定,可以自行设置调度策略与优先级。<br/>其中继承策略必须为PTHREAD_EXPLICIT_SCHED,否则设置线程的优先级会被忽略。</p><p class="artical_littlestyle2">2、程序示例</p><p style="text-indent: 2em;">下面是一个简单的设置优先级的程序示例,通过修改任务1与任务2的优先级高低,可以观察到打印信息中,先打印的是优先级高的任务的信息:</p><pre class="brush:cpp;toolbar:false PrismJs">/* ******************************************************************************** *描述:设置线程优先级 *Use:gcc&nbsp;prio.c&nbsp;-lpthread *By:Ailson&nbsp;Jack *Date:2016.03.25 *Blog:www.only2fire.com ******************************************************************************** */ #include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;stdio.h&gt; #include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;stdlib.h&gt; #include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;unistd.h&gt; #include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;pthread.h&gt; #include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string.h&gt; #include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;time.h&gt; //在用户层或者应用层,1表示优先级最低,99表示优先级最高 #define&nbsp;Task1_Prio&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6 #define&nbsp;Task2_Prio&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7 pthread_barrier_t&nbsp;barrier; void&nbsp;*Task1(void&nbsp;*arg); void&nbsp;*Task2(void&nbsp;*arg); int&nbsp;main(void) { &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;policy,inher; &nbsp;&nbsp;&nbsp;&nbsp;pthread_t&nbsp;tid; &nbsp;&nbsp;&nbsp;&nbsp;pthread_attr_t&nbsp;attr; &nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;sched_param&nbsp;param; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;pthread_barrier_init(&amp;barrier,NULL,2+1); &nbsp;&nbsp;&nbsp;&nbsp;//初始化线程属性 &nbsp;&nbsp;&nbsp;&nbsp;pthread_attr_init(&amp;attr); &nbsp;&nbsp;&nbsp;&nbsp;//获取继承的调度策略 &nbsp;&nbsp;&nbsp;&nbsp;pthread_attr_getinheritsched(&amp;attr,&amp;inher); &nbsp;&nbsp;&nbsp;&nbsp;if(inher&nbsp;==&nbsp;PTHREAD_EXPLICIT_SCHED) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;PTHREAD_EXPLICIT_SCHED\r\n&quot;); &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if(inher&nbsp;==&nbsp;PTHREAD_INHERIT_SCHED) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;PTHREAD_INHERIT_SCHED\r\n&quot;); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//必需设置inher的属性为&nbsp;PTHREAD_EXPLICIT_SCHED,否则设置线程的优先级会被忽略 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inher&nbsp;=&nbsp;PTHREAD_EXPLICIT_SCHED; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//设置继承的调度策略 &nbsp;&nbsp;&nbsp;&nbsp;//具有root权限的用户才能执行pthread_attr_setinheritsched操作, &nbsp;&nbsp;&nbsp;&nbsp;//否则创建线程会失败 &nbsp;&nbsp;&nbsp;&nbsp;pthread_attr_setinheritsched(&amp;attr,inher); &nbsp;&nbsp;&nbsp;&nbsp;//设置线程调度策略 &nbsp;&nbsp;&nbsp;&nbsp;policy&nbsp;=&nbsp;SCHED_FIFO; &nbsp;&nbsp;&nbsp;&nbsp;pthread_attr_setschedpolicy(&amp;attr,policy); &nbsp;&nbsp;&nbsp;&nbsp;//设置调度参数 &nbsp;&nbsp;&nbsp;&nbsp;param.sched_priority&nbsp;=&nbsp;Task1_Prio; &nbsp;&nbsp;&nbsp;&nbsp;pthread_attr_setschedparam(&amp;attr,&amp;param); &nbsp;&nbsp;&nbsp;&nbsp;//创建线程 &nbsp;&nbsp;&nbsp;&nbsp;pthread_create(&amp;tid,&nbsp;&amp;attr,Task1,NULL); &nbsp;&nbsp;&nbsp;&nbsp;//设置调度参数 &nbsp;&nbsp;&nbsp;&nbsp;param.sched_priority&nbsp;=&nbsp;Task2_Prio; &nbsp;&nbsp;&nbsp;&nbsp;pthread_attr_setschedparam(&amp;attr,&amp;param); &nbsp;&nbsp;&nbsp;&nbsp;//创建线程 &nbsp;&nbsp;&nbsp;&nbsp;pthread_create(&amp;tid,&nbsp;&amp;attr,Task2,NULL); &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;sleep(1); &nbsp;&nbsp;&nbsp;&nbsp;pthread_barrier_wait(&amp;barrier); &nbsp;&nbsp;&nbsp;&nbsp;pthread_join(tid,&nbsp;NULL); } void&nbsp;*Task1(void&nbsp;*arg) { &nbsp;&nbsp;&nbsp;&nbsp;pthread_barrier_wait(&amp;barrier); &nbsp;&nbsp;&nbsp;&nbsp;while(1) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;Task1&nbsp;is&nbsp;running.\r\n&quot;); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(3);//延时3s &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL); } void&nbsp;*Task2(void&nbsp;*arg) { &nbsp;&nbsp;&nbsp;&nbsp;pthread_barrier_wait(&amp;barrier); &nbsp;&nbsp;&nbsp;&nbsp;while(1) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;Task2&nbsp;is&nbsp;running.\r\n&quot;); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(3);//延时3s &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL); }</pre><p style="text-indent: 2em;">编译运行程序,由于任务2的优先级比任务1的优先级高,因此打印信息,先打印的是任务2,截图如下:</p><p style="text-align:center"><img src="/uploads/AilsonJack/2018.08.25/1535208836832121.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.25/1535208836832121.png&#39;)"/></p><p style="text-indent: 2em;">接着将任务1的优先级设置为最高的,然后编译,试试看是否符合自己的预期。</p><p style="text-indent: 2em;"><span style="color: rgb(255, 0, 0);">注:</span>上述的测试是在<span style="color: rgb(255, 0, 0);">单核系统</span>中进行的测试(虚拟机设置为单核),对于普通进程的调度,是CPU根据进程优先级算出时间片,这样并不能一定保证高优先级的进程一定先运行,只不过和优先级低的进程相比,通常优先级较高的进程获得的CPU时间片会更长而已。其实,如果要想保证一个线程运行完再运行另一个线程的话,还要使用多线程的同步技术,信号量,条件变量等方法。而不是绝对依靠优先级的高低,来保证。<br/></p>
欢迎关注博主的公众号呀,精彩内容随时掌握:
热情邀请仔细浏览下博客中的广告,万一有对自己有用或感兴趣的呢。◕ᴗ◕。。
如果这篇文章对你有帮助,记得点赞和关注博主就行了^_^,当然了能够赞赏博主,那就非常感谢啦!
注: 转载请注明出处,谢谢!^_^
广告位C招租:2
广告位C招租:3
转载请注明来源: 本文链接:  By: AilsonJack
Linux编程-线程优先级的设定  |  说好一起走
广告位D招租:1
广告位D招租:2
暂无评论,要不要来个沙发
发表评论

 
广告位E招租
Copyright © 2015~2021  说好一起走   保留所有权利   |  百度统计  蜀ICP备15004292号