在做音视频同步之前我们需要先补充一下C中的线程知识。
函数定义:pthread_create函数 原型:int pthread_create((pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) 用法:#include 功能:创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。
说明: thread:线程标识符;
attr:线程属性设置;
start_routine:线程函数的起始地址;
arg:传递给start_routine的参数;
返回值:成功,返回0;出错,返回-1。
函数定义: int pthread_join(pthread_t thread, void **retval);
pthread_join()函数,以阻塞的方式等待thread指定的线程结束,线程间同步的操作
当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。是不是感觉有点像pthread_create中传入的方法的回调。
函数定义:int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
posix下抽象了一个锁类型的结构:ptread_mutex_t。通过对该结构的操作,来判断资源是否可以访问。
顾名思义,加锁(lock)后,别人就无法打开,只有当锁没有关闭(unlock)的时候才能访问资源。
即对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,
这个标记用来保证在任一时刻,只能有一个线程访问该对象。
编译:gcc mik.c -o mik -lpthread
输出:
rval 输出的就是退出时传入的值
然后搞个多线程试试:
输出结果假设这两个线程是视频或者音频播放的线程,当一帧视频画面播放出来对应的要播放音频声音,只有这个声音播放完了,才能播放下一帧的画面,这样才能实现声音和画面一致的效果。
加锁实现一个线程执行完在执行下一个线程:
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
posix下抽象了一个锁类型的结构:ptread_mutex_t。通过对该结构的操作,来判断资源是否可以访问。
顾名思义,加锁(lock)后,别人就无法打开,只有当锁没有关闭(unlock)的时候才能访问资源。
即对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,
这个标记用来保证在任一时刻,只能有一个线程访问该对象。
参数一 创建一个锁
参数二指定了新建互斥锁的属性。如果参数attr为NULL,则使用默认的互斥锁属性,默认属性为快速互斥锁
PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
* PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。
* PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。
PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。
输出结果
生产者和消费者:
解码一帧视频,播放一帧视频也就是生产者、消费者模式 。
网友评论