st_cond_wait协程间通信介绍—StateThreads基础函数介绍
作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音
我们在进行多线程编程的时候,有时候我们需要设计一个 生产者线程 跟 消费者线程,然后他们之间通过 pthread_cond_signal()
跟 pthread_cond_wait()
进行通信。
提示:如果不熟悉多线程编程,以及线程同步的知识,请阅读《Unix环境高级编程》第11章节。
StateThreads 也为我们提供了类似的函数来实现 生产者协程 跟 消费者协程,就是 st_cond_signal()
跟 st_cond_wait()
下面我通过一个小例子 sync.c
演示一下这两个函数的作用。
#include <stdio.h>
#include <memory.h>
#include "st.h"
#include "../common.h"
st_cond_t *cond_name;
char data[100] = {};
void *publish(void *arg) {
st_usleep(0.5 * 1000 * 1000LL);
strcpy(data,"srs-principle");
st_utime_t time_now = st_utime();
printf("Pulish name %s, %lld\r\n",data, time_now);
st_cond_signal(cond_name);
printf("publish exit \n");
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_utime_t time_now = st_utime();
printf("Consume name %s, %lld\r\n",data, time_now);
printf("Consume exit \n");
return NULL;
}
int main(int argc, char *argv[]) {
st_init();
st_thread_t threads[3] = {0};
cond_name = st_cond_new();
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(3 * 1000 * 1000LL);
printf("st_thread_exit success \n");
st_cond_destroy(cond_name);
//退出当前 main 协程
st_thread_exit(NULL);
/* 不会运行到这里 */
return 1;
}
请把 sync.c
放到 example
目录下。然后我们修改一下 makefile
的编译规则,修改的地方如下:
EXAMPLES = $(OBJDIR)/lookupdns $(OBJDIR)/proxy $(OBJDIR)/sync
改为
EXAMPLES = $(OBJDIR)/lookupdns $(OBJDIR)/proxy $(OBJDIR)/server $(OBJDIR)/sync
$(OBJDIR)/server: server.c $(OBJDIR)/error.o $(LIBST) $(HEADER)
$(CC) $(CFLAGS) -I$(INCDIR) server.c $(OBJDIR)/error.o $(LIBST) $(EXTRALIBS) -o $@
加上 下面这句
$(OBJDIR)/sync: sync.c $(LIBST) $(HEADER)
$(CC) $(CFLAGS) -I$(INCDIR) sync.c $(LIBST) $(EXTRALIBS) -o $@
sync
程序的运行效果如下:
st_cond_wait()
负责等待信号通知,st_cond_signal()
负责发送信号通知。可以看到启动了 3 个消费者协程,但是只有一个消费协程被激活了。
你也可以用 st_cond_broadcast() 来广播信号给所有的协程,让他们都激活。
sync.c
里面有个重点,就是 Consume 协程要比 Publish 协程先运行,要不会丢失通知。
协程的 st_cond_wait()
跟 线程的 pthread_cond_wait()
还是有一些区别的,pthread_cond_wait()
需要一把锁,而 st_cond_wait()
不需要锁
参考资料