美文网首页
C代码线程锁结合工作Bookmark功能的实现

C代码线程锁结合工作Bookmark功能的实现

作者: Spirituality韬 | 来源:发表于2019-01-02 15:18 被阅读0次
  • 需求如下:播放刻录文件时退出时要求保留offset,下次在播放时seek。客户需求很简单,但是领导要求拓展功能,防止中途突然断电的这种情况,要求播放过程中每隔30s保存bookmark。

接口已经封装这里只看一小部分,添加Bookmark代码

JT_StatusCode_t JTAPIBOOKMARK_AddBookMark(PST_JTAPIBOOKMARK_Data pstData)
{
#ifdef ANDROID_PLATFORM
    JT_S8 path[128] = {0};
    JT_S8 *tmp = strrchr(pstData->file, '/');
    int size = tmp - pstData->file;
    memcpy(path, pstData->file, size);
    JTHDIVFS_ChangeCurrentDir(path);
#else
    JTHDIVFS_ChangeCurrentDir("/");
#endif
    JT_StatusCode_t status_code = JT_SUCCESS;
    JT_U8 msg[128];
    FILE * fd;
    system("mv Bookmark.xml bookmark.xml");
    fd = fopen("Bookmark.xml","a+");
    fputs("<Bookmark>\n",fd);
    memset(msg ,0 ,128);
    sprintf(msg ,"<filename>%s</filename>\n",pstData->file);
    fputs(msg ,fd);
    memset(msg ,0 ,128);
    sprintf(msg ,"<offset>%d</offset>\n", pstData->u64seekoffset);
    fputs(msg ,fd);
    fputs("</Bookmark>\n",fd);
    if (fclose(fd) != 0)
    {
        status_code = JT_FAILED;
    }
    system("cat bookmark.xml >> Bookmark.xml");
    system("rm -f bookmark.xml");
    JTHDIVFS_ChangeCurrentDir("/");
    return status_code;
}

代码很简单,因为之前都是在Linux平台上面使用,这里自己修改用Android 宏隔开,Bookmark.xml要求保存在同刻录文件目录下,BookMark结构体由filename(路径/文件名)和offset构成十分简单。

整体逻辑也很容易实现,在播放时查询有没有Bookmark,如果有,seek offset,然后删除Bookmark(防止有多个Bookmark),退出时,保存Bookmark。

现在就是拓展需求,要求每隔30s去添加Bookmark。开启个线程来做此操作,但是C代码来实现线程并没有什么经验,于是去网上查找的部分解决方案。

static pthread_mutex_t mutex;
static pthread_cond_t cond;
static int flag = 0;
//static char cur_play_name[256]; 
    
void srpthread_init()
{
    pthread_mutex_init(&mutex,NULL);
    pthread_cond_init(&cond,NULL);
}
 
void srpthread_suspend()
{
    pthread_mutex_lock(&mutex);
    flag--;
    pthread_mutex_unlock(&mutex);
}
 
 
void srpthread_resume()
{
    pthread_mutex_lock(&mutex);
    flag++;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
}

static void StartBookMark(void *args)
{
    PST_JTAPIBOOKMARK_Data pstData;
    JTAPIMedia_PlayStatusParams_t play_status ;
    pstData = (PST_JTAPIBOOKMARK_Data)JTOS_MemMalloc(sizeof(ST_JTAPIBOOKMARK_Data));
    while(1)
    {
        pthread_mutex_lock(&mutex);
        while(flag<=0)
        {
            pthread_cond_wait(&cond,&mutex);
        }
        pthread_mutex_unlock(&mutex);
        sleep(30);
        ....
    }
}

StartBookMark是线程执行函数,利用锁来控制线程的执行,逻辑大致是播放开始时resume 释放锁,将会开始执行sleep之后的代码(添加Bookmark)然后循环,stop时调用suspend,然后在pthread_cond_wait(&cond,&mutex)处等待下一次的resume

感觉一切完美,没有什么毛病,自己也测试了一下功能OK吗,但是领导review一下代码,代码不够规范(什么可能编译不能通过,反正不太懂),要改用海思的接口来实现这个方案。

莫名其妙地自己又去看海思的接口,然后看看在接口在其他部分是怎么调用的,最后找嵌入式同事帮忙。

static JTOS_QueueId_t g_bookmark_queue = JT_INVALID_ID;
static JTOS_TaskId_t g_bookmark_task = JT_INVALID_ID;
static JTOS_MutexId_t bookmark_mutex_id = JT_INVALID_ID;

static int flag = 0;

#define mutex_Lock() \
do { \
    if(JT_INVALID_ID == bookmark_mutex_id) \
    { \
         (void)JTOS_MutexCreate(&bookmark_mutex_id); \
    } \
     \
    if((JT_INVALID_ID == bookmark_mutex_id) || (JT_SUCCESS != JTOS_MutexLock(bookmark_mutex_id, JTOS_TIMEOUT_INFINITY))) \
    { \
        JT_ERROR(("JTOS_MutexCreate or JTOS_MutexLock ird_mutex_id Failed\n")); \
    } \
}while(0)

#define mutex_Unlock() \
do { \
    if(JT_INVALID_ID == bookmark_mutex_id) \
    { \
        (void)JTOS_MutexCreate(&bookmark_mutex_id); \
    } \
         \
    if((JT_INVALID_ID == bookmark_mutex_id) || (JT_SUCCESS != JTOS_MutexUnlock(bookmark_mutex_id))) \
    { \
        JT_ERROR(("JTOS_MutexCreate or JTOS_MutexUnlock ird_mutex_id Failed\n")); \
    } \
}while(0)   

 
void srpthread_suspend()
{
    mutex_Lock();
    flag--;
    mutex_Unlock();
}
 
 
void srpthread_resume()
{
    JT_U32 au32Msg[4] = {0};
    mutex_Lock();
    flag++;
    JTOS_QueueSend(g_bookmark_queue, au32Msg, JTOS_TIMEOUT_IMMEDIATE);
    mutex_Unlock();
}

static void StartBookMark(void *args)
{
    JT_StatusCode_t enStatusCode = JT_SUCCESS;
    JT_U32 au32Msg[4] = {0};
    PST_JTAPIBOOKMARK_Data pstData;
    JTAPIMedia_PlayStatusParams_t play_status ;
    pstData = (PST_JTAPIBOOKMARK_Data)JTOS_MemMalloc(sizeof(ST_JTAPIBOOKMARK_Data));
    while(1)
    {
        while(flag <= 0)
        {
            enStatusCode = JTOS_QueueReceive(g_bookmark_queue, au32Msg, JTOS_TIMEOUT_INFINITY);
        }
        ...
    }
}

逻辑和之前差不多只是,换用了海思的接口,利用Send 、Receive形式来使用等待操作

相关文章

  • C代码线程锁结合工作Bookmark功能的实现

    需求如下:播放刻录文件时退出时要求保留offset,下次在播放时seek。客户需求很简单,但是领导要求拓展功能,防...

  • leetcode第1114题:按顺序打印

    题目描述 考点 多线程 代码实现 注意利用了c++标准模板库中:mutex库; 参考资料 c++之多线程中“锁”的...

  • 用C语言对Python进行扩展

    python C 扩展代码优点: 可以添加额外的功能:Python的多线程模型受限于GIL锁,自身提供的多线程模型...

  • AbstractQueuedSynchronizer

    理解多线程的并发锁,可结合多进程的分布式锁(如Zookeeper的互斥锁、读写锁的实现原理),本质是相通的 介绍 ...

  • 2020-02-29 CountDownLatch

    中文名 倒计时闩锁 功能 通过计数器功能,控制线程的执行顺序。 代码示例 代码示例介绍 在子线程完成任务后,才开始...

  • 枚举来实现单例

    双重校验锁 实现单例: 枚举 实现单例: 上面的双重锁校验的代码很臃肿,是因为大部分代码都是在保证线程安全。为了在...

  • JUC(一) | 同步辅助类浅谈

    Java多线程环境中存在内置锁与同步锁,内置锁即由synchronized修饰的代码,借助于对象的内置锁实现,为重...

  • iOS开发中常用的几种锁

    iOS开发中常用的几种锁 简介: 操作系统在进行多线程调度的时候,为了保证多线程安全引入了锁的机制,以实现指定代码...

  • C++: range的实现

    使用C++实现一个range, 功能如下: 实现代码如下:

  • java-summery

    1、对象锁和类锁 java的内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁。线程进入同步代码...

网友评论

      本文标题:C代码线程锁结合工作Bookmark功能的实现

      本文链接:https://www.haomeiwen.com/subject/lapzlqtx.html