st_thread_interrupt中断协程介绍—StateThreads协程源码分析
作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音
st_thread_interrupt() 函数用于中断一个正在阻塞的协程,例如 协程A 阻塞在 st_cond_wait()
里等待条件变量的通知,或者 阻塞在 st_read()
里面等待网络数据到来。如果你不想等了,就可以用 st_thread_interrupt()
函数来让这个 协程A 停止等待,立即返回,这就是中断。
st_thread_interrupt()
可以中断所有的 阻塞函数。
之前《st_cond_wait协程间通信介绍》的 sync
是无法正常退出的,是因为其他 2 个协程一直阻塞在 st_cond_wait()
,所以导致整个线程无法退出。
我们现在就用 st_thread_interrupt()
来中断其他两个协程,让程序可以正常退出。
sync_interrupt.c
的代码如下:
#include <stdio.h>
#include <memory.h>
#include "st.h"
#include "../common.h"
st_cond_t *cond_name;
st_mutex_t* mutex_name;
char data[100] = {};
void *publish(void *arg) {
st_usleep(0.5 * 1000 * 1000LL);
st_mutex_lock(mutex_name);
memset(data,0,100);
strcpy(data,"srs-principle");
st_utime_t time_now = st_utime();
printf("Pulish name %s, %lld\r\n",data, time_now);
st_mutex_unlock(mutex_name);
st_cond_signal(cond_name);
return NULL;
}
void *consume(void *arg) {
int ret;
printf("Consume start \n");
ret = st_cond_wait(cond_name);
printf("st_cond_wait return %d \n",ret);
st_mutex_lock(mutex_name);
st_utime_t time_now = st_utime();
printf("Consume name %s, %lld\r\n",data, time_now);
st_mutex_unlock(mutex_name);
return NULL;
}
int main(int argc, char *argv[]) {
st_init();
cond_name = st_cond_new();
mutex_name = st_mutex_new();
st_thread_t threads[3] = {0};
st_thread_create(publish, NULL, 0, 0);
threads[0] = st_thread_create(consume, NULL, 0, 0);
threads[1] = st_thread_create(consume, NULL, 0, 0);
threads[2] = st_thread_create(consume, NULL, 0, 0);
st_usleep(2 * 1000 * 1000LL);
for (int i = 0; i < 3; ++i) {
if( threads[i]->state == _ST_ST_COND_WAIT ){
printf("thread %d is block \n",i );
st_thread_interrupt(threads[i]);
}
}
st_cond_destroy(cond_name);
st_mutex_destroy(mutex_name);
printf("st_thread_exit success \n");
//退出当前 main 协程
st_thread_exit(NULL);
/* 不会运行到这里 */
return 1;
}
makefile
的修改规则,请参考前面的文章。
运行结果如下:
可以看到程序正常退出了。正常收到通知被唤醒的 st_cond_wait()
返回的是 0 ,而被中断的唤醒的 st_cond_wait()
返回的是 -1
还有一个 st_cond_timedwait() 函数可以只等待指定的时间就立即返回
关于 st_thread_interrupt()
的内部实现分析,请阅读《st_thread_interrupt中断协程原理》