linux中线程例子,Linux多线程编程(3)——实例分析

1、背景说明:

MJPG-streamer是一个开源软件,它可从一个输入插件复制JPG帧到多个输出插件。它的输入插件从摄像头、文件系统或其它输入插件读取视频数据,并复制到内存中,它有多个输出插件将这些视频数据经过处理,其中最重要的输出插件是网站服务器插件,它将视频帧以M-JPEG流的形式通过基于ip的网络传输到浏览器如Firefox,Cambozola,VLC播放器,Windows的移动设备或者其他拥有浏览器的移动设备。MJPG-streamer的工作就是将其中的一个输入插件和多个输出插件绑定在一起,所有的工作都是通过它的各个插件完成的。

2、代码分析

本例中输入插件实现从摄像头抓取视频帧,并复制到一个全局缓存;输出插件实现从该缓存中读取帧,并保存为当地视频文件。

input_run/output_run、input_stop/output_stop均在主函数中被调用。每次调用时input_run/output_run都创建一个新线程,input_stop/output_stop终止该线程。void *cam_thread(void *arg)与void *worker_thread(void *arg)分别为其对应的线程启动函数。其中使用了互斥量+条件变量对线程进行同步。

2.1输入插件关键实现代码

/******************************************************************************

Description.: spins of a worker thread

******************************************************************************/

intinput_run(int id)

{

/* create thread and pass context to thread function */

pthread_create(&(cams[id].threadID), NULL, cam_thread, &(cams[id]));

pthread_detach(cams[id].threadID);

return 0;

}

/******************************************************************************

Description.: this thread worker grabs a frame from camera and copies it to the global buffer

******************************************************************************/

void*cam_thread(void *arg)

{

/* set cleanup handler to cleanup allocated ressources */

pthread_cleanup_push(cam_cleanup, pcontext);

while(!pglobal->stop) {

/* copy JPG picture to global buffer */

pthread_mutex_lock(&pglobal->in[pcontext->id].db);

pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, pcontext->videoIn->tmpbuffer, pcontext->videoIn->buf.bytesused);

/* copy this frame's timestamp to user space */

pglobal->in[pcontext->id].timestamp = pcontext->videoIn->buf.timestamp;

/* signal fresh_frame */

pthread_cond_broadcast(&pglobal->in[pcontext->id].db_update);

pthread_mutex_unlock(&pglobal->in[pcontext->id].db);

}

DBG("leaving input thread, calling cleanup function now\n");

pthread_cleanup_pop(1);

}

/******************************************************************************

Description.: Stops the execution of worker thread

******************************************************************************/

intinput_stop(int id)

{

DBG("will cancel camera thread #%02d\n", id);

pthread_cancel(cams[id].threadID);

return 0;

}

2.2输出插件关键实现代码

/******************************************************************************

Description.: calling this function creates and starts the worker thread

******************************************************************************/

intoutput_run(int id)

{

DBG("launching worker thread\n");

pthread_create(&worker, 0, worker_thread, NULL);

pthread_detach(worker);

return 0;

}

/******************************************************************************

Description.: this is the main worker thread

it loops forever, grabs a fresh frame from gloable buffer and stores it to file

******************************************************************************/

void*worker_thread(void *arg)

{

/* set cleanup handler to cleanup allocated ressources */

pthread_cleanup_push(worker_cleanup, NULL);

while(ok >= 0 && !pglobal->stop) {

DBG("waiting for fresh frame\n");

pthread_mutex_lock(&pglobal->in[input_number].db);

pthread_cond_wait(&pglobal->in[input_number].db_update, &pglobal->in[input_number].db);

/* copy frame to our local buffer now */

memcpy(frame, pglobal->in[input_number].buf, frame_size);

/* allow others to access the global buffer again */

pthread_mutex_unlock(&pglobal->in[input_number].db);

}

/* cleanup now */

pthread_cleanup_pop(1);

}

/******************************************************************************

Description.: calling this function stops the worker thread

******************************************************************************/

intoutput_stop(int id)

{

DBG("will cancel worker thread\n");

pthread_cancel(worker);

return 0;

}

—wicoboy

2013/8/24

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值