【linux菜鸟第一帖】:请问多线程开发,为何不能设置多个线程的优先级问题?

jessiepan 2009-04-22 03:32:37
代码如下:
pthread_t id_encode;
pthread_t id_decode;
pthread_attr_t attr;
struct sched_param param;
int newprio;

newprio=25;
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr,SCHED_RR);
pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);
pthread_attr_getschedparam(&attr, ¶m);
param.sched_priority=newprio;
pthread_attr_setschedparam(&attr, ¶m);
ret = pthread_create(&id_encode,&attr,(void*)encode_thread,NULL);
if ( 0 != ret )
{
trace( "create encode_thread thread error\n");
goto RELEASE;
}
pthread_attr_destroy(&attr);
printf("1.create encode_thread ok!\n");

pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr,SCHED_RR);
pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);
newprio=17;
pthread_attr_getschedparam(&attr, ¶m);
param.sched_priority=newprio;
pthread_attr_setschedparam(&attr, ¶m);
ret = pthread_create(&id_decode,&attr,(void*)decode_thread,NULL);
if ( 0 != ret )
{
trace( "create decode_thread thread error\n");
goto RELEASE;
}
pthread_attr_destroy(&attr);
printf("2.create decode_thread ok!\n");

运行之后,在超级终端的输出信息,只有: 1.create encode_thread ok! , 然后感觉程序就死掉了?系统也没有继续往下面跑?..
不知道我在创建第二个线程的时候,有关线程属性参数的设置有什么问题?? 难道是优先级的设置不对吗???
...全文
238 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
jessiepan 2011-04-26
  • 打赏
  • 举报
回复
我是楼主!

最近在调试arm-linux下的多线程程序,痛苦ing。。。发现一些跟多线程有关的异常,实在是查找不到原因了。

我想请问下,我现在arm-linux下用的是libpthread-2.5.so的库,如果想替换成libpthread-2.8.so的库,是直接替换就可以了吗?还是有其他相关的一些依赖库,都要替换成2.8版本的?比如:libc-2.8.so 等等
为什么网上google不到libpthread的源码?现在arm-linux下最新的libpthread库是不是2.8版本的?
jessiepan 2011-03-07
  • 打赏
  • 举报
回复
再补充说明一下上面的问题。

我是在嵌入式的处理器Ambarella A2平台上,开发H.264 1080P的ipcam,使用Live555作为Streamserver完成rtsp、rtp视音频的传输。现在已经将A2 encode出来的video buffer通过有名管道推给rtsp_server,PC端用VLC1.0.1也可以打开rtsp://192.168.1.238/stream1链接,看到视频图像。

目前的问题:
rtsp_server这个进程大概每次运行不超过10分钟,有时候两三分钟,有时候五六分钟,就会挂掉,提示:Segmentation fault!导致VLC自动关闭,或是支持crash掉。。。?
因为代码比较多,一下子也不太好找,具体是哪个地方的问题。。初步怀疑,可能是自己写的一个FIFO Buffer哪里没写好?
想请教高手,有没有什么好的办法或是辅助工具,来调试嵌入式板子上跑的arm-linux程序呢??
jessiepan 2011-03-04
  • 打赏
  • 举报
回复
谢谢楼上的大哥,有名管道的读、写终于搞定了!

贴部分相关代码如下:
/*这个是写进程的代码片段
#define FIFO_NAME "/tmp/video_fifo"
bits_info_t *desc;
int pipe_fd,res,ret;
u32 pic_size = desc->pic_size;

if (access(FIFO_NAME,F_OK)==-1)
{
ret = mkfifo(FIFO_NAME,0666);
if (ret != 0)
{
printf("Could not create video_fifo! \r\n");
}
}

while(video_buffer==NULL)video_buffer = new char[1024*512];
memcpy(video_buffer,(void*)desc->start_addr,pic_size);

pipe_fd = open(FIFO_NAME, O_WRONLY);
printf("Write pipe the file's descriptor is %d\n",pipe_fd);
if (pipe_fd != -1)
{
res = write(pipe_fd,desc,sizeof(bits_info_t));
res = write(pipe_fd,&pic_size,sizeof(pic_size));
res = write(pipe_fd,video_buffer,pic_size);
printf("write pipe video_buffer size is %d\n",pic_size);
if (res == -1)
{
printf("Write ERROR on pipe! \r\n");
}
else
{
printf("Write OK on pipe! \r\n");
close(pipe_fd);
}
}
==================================================================================

/*这个是读进程的代码片段
#define FIFO_NAME "/tmp/video_fifo"
#define bufSize 512*1024
bits_info_t desc;
char vbuffer[bufSize];
u32 vbuf_size;

pipe_fd = open(FIFO_NAME, O_RDONLY);
printf("the read pipe video_fifo file's descriptor is %d\n",pipe_fd);
if (pipe_fd != -1)
{
bytes_read = read(pipe_fd, &desc,sizeof(desc));
bytes_read = read(pipe_fd, &vbuf_size, sizeof(vbuf_size));
printf("the read pipe video_fifo video buffer size is %d\n",vbuf_size);
bytes_read = read(pipe_fd, vbuffer, vbuf_size);
close(pipe_fd);
}
==================================================================================

不过,小弟我还有个新的问题:
想问下各位老大,在Linux下有什么比较好用的检查程序代码 内存泄露 或 内存访问越界的 工具吗?
我现在那个读管道数据的进程,大概每次运行10分钟左右后,就会挂掉,提示:Segmentation fault!
因为代码比较多,一下子也不太好找,具体是哪个地方的问题。。所以,只好先求助于代码检查工具了
justkk 2011-02-26
  • 打赏
  • 举报
回复
管道的容量限制不影响你的数据传输吧
写入时,如果管道已满,那就阻塞
读进程从管道中读取数据之后,管道有剩余空间,写进程就可以继续写入了
jessiepan 2011-02-25
  • 打赏
  • 举报
回复
我是楼主!再补充说明一下上面的问题。

因为这两个进程比较大,比较复杂,所以有关读管道和写管道的代码,不是简单的写在每个进程代码的main里,而是在进程里又另外有开线程,读、写管道的代码是分别放在各自不同的线程中运行的。这样写,会有什么问题吗?

另外,我目前是在嵌入式的处理器上,开发H.264 1080P的ipcam。这两个进程,一个是encode视频编码的进程,另外一个是rtsp网络视频数据传输的进程,我实际上是想完成这样一个功能:把encode好出来的一帧帧视频数据直接推给网络进程,进行传输。
当码流(Bitrate)设置比较大,比如:10Mbps以上时,视频画面运动量比较大的情况下,1080P H.264编码出来的一帧数据,可能有达到上百KB,所以,我的video_buffer开了512KB。我不知道是不是因为这个buffer太大了的原因,导致linux下的写管道出现了问题?难道要把我video_buffer里的frame拆包再来传输么?? 哎,郁闷了。。

请问高手,Linux下的有名管道,最大可以一次传输多大的数据块呀?
jessiepan 2011-02-24
  • 打赏
  • 举报
回复
我是楼主,没想到这个帖子还在这里?借地方再问个Linux下编程的问题,关于linux下两个进程如何通过有名管道传输数据。。

贴部分相关代码如下:
/*这个是写进程的代码片段
#define FIFO_NAME "/tmp/video_fifo"
bits_info_t *desc;
int pipe_fd,res,ret;
u32 pic_size = desc->pic_size;

if (access(FIFO_NAME,F_OK)==-1)
{
ret = mkfifo(FIFO_NAME,0777);
if (ret != 0)
{
printf("Could not create video_fifo! \r\n");
}
}

while(video_buffer==NULL)video_buffer = new char[1024*512];
memcpy(video_buffer,(void*)desc->start_addr,pic_size);

pipe_fd = open(FIFO_NAME, O_WRONLY);
printf("Write pipe the file's descriptor is %d\n",pipe_fd);
if (pipe_fd != -1)
{
res = write(pipe_fd,desc,sizeof(desc));
res = write(pipe_fd,&pic_size,sizeof(pic_size));
res = write(pipe_fd,video_buffer,pic_size);
printf("write pipe video_buffer size is %d\n",pic_size);
if (res == -1)
{
printf("Write ERROR on pipe! \r\n");
}
else
{
printf("Write OK on pipe! \r\n");
close(pipe_fd);
}
}
=============================================================================

/*这个读进程的代码片段
video_buf = (u8 *)malloc(1024*512);
pipe_fd = open(FIFO_NAME, O_RDONLY);
printf("the read pipe video_fifo file's descriptor is %d\n",pipe_fd);
if (pipe_fd != -1)
{
bytes_read = read(pipe_fd, desc,sizeof(desc));
bytes_read = read(pipe_fd, vbuf_size, sizeof(vbuf_size));
printf("the read pipe video_fifo video buffer size is %d\n",vbuf_size);
bytes_read = read(pipe_fd, video_buf, vbuf_size);
close(pipe_fd);
}
==============================================================================

感觉可能是我这个管道没用好,反正不是写管道不对,就是读管道读不到数据。。。是不是跟我那个video_buffer,定义成512KB,太大了?写管道写不了吗??

期待高手过来指点下迷茫的linux菜鸟!
jessiepan 2009-04-23
  • 打赏
  • 举报
回复
嗯,谢谢楼上的朋友! 不过,你的这段测试代码在我的机器上跑起来,还是有问题,超级终端上依然没有 2.create decode_thread ok! 的输出.
先说明一下我的系统环境,arm-linux-kernel 2.4.19,arm-linux-gcc 2.95.3,使用的嵌入式芯片:GM8120.

上面的问题,后来我是这样解决的:把有关线程属性的设置代码放到每一个线程体内执行,所有的线程就可以全部创建起来了.有点奇怪,问题是解决了,但不知道原因何在? 我看其他有关linux下多线程编程的书籍,都是在创建一个新线程之前做线程属性参数的设置的吧? 没有说,要把线程属性的设置放到线程函数体里来写的..

又有一个新问题:
我把encode_thread的优先级从25逐步加大到80,线程里打印输出的编码帧率一直是 21 fps没有改变? 按道理,编码线程应该要随着线程本身优先级的加大而有所提高的吧?为何编码帧率一直都没有改变呢??
子晞 2009-04-23
  • 打赏
  • 举报
回复
简单的测试了下,你看下面的代码:

//pthread2.c
#include <stdio.h>
#include <pthread.h>
//#include <sys/sched.h>
void encode_thread()
{
}
void decode_thread()
{
}
int main(){
pthread_t id_encode;
pthread_t id_decode;
pthread_attr_t attr;
struct sched_param param;
int newprio;
int ret;
newprio=25;
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr,SCHED_RR);
pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);
pthread_attr_getschedparam(&attr, ¶m);
param.sched_priority=newprio;
pthread_attr_setschedparam(&attr, ¶m);
ret = pthread_create(&id_encode,&attr,(void*)encode_thread,NULL);
if ( 0 != ret )
{
fprintf(stderr, "create encode_thread thread error\n");
return -1;
}
pthread_attr_destroy(&attr);
printf("1.create encode_thread ok!\n");

pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr,SCHED_RR);
pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);
newprio=17;
pthread_attr_getschedparam(&attr, ¶m);
param.sched_priority=newprio;
pthread_attr_setschedparam(&attr, ¶m);
ret = pthread_create(&id_decode,&attr,(void*)decode_thread,NULL);
if ( 0 != ret )
{
fprintf(stderr, "create decode_thread thread error\n");
return -1;
}
pthread_attr_destroy(&attr);
printf("2.create decode_thread ok!\n");
return 0;
}

运行结果

$gcc pthread2.c -lpthread
$./a.out
1.create encode_thread ok!
2.create decode_thread ok!

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧