一、概念
伪线程时一种基于socket的与外部通讯的统一架构,免除了每个用户空间模块编写基于socket的代码的时候都需要编写一套基础框架。同时,伪线程能够使代代码的结构更加清晰,更具有可读性。
伪线程与线程区别:
①伪线程并不是真正意义上的操作系统线程,不在操作系统的调度队列中。
②通常创建一个真实的线程,然后在这个线程中进行伪线程调度。
③伪线程相当于在操作系统线程之上的一个线程调度机制。
④伪线程不能代替线程。当需要并发或挂起的操作时仍需要使用线程。
二、设计考虑问题
①伪线程不是真正的线程,不存在两个伪线程同时运行的情况,一旦某一个伪线程被调度,则一直到这个伪线程执行完毕之前,不会有任何中断。
②一套伪线程的操作必须在同一个线程里面。不允许多个线程同时操作同一个伪线程,所以临界资源都需要进行保护。
③本线程中的所以伪线程的操作不能用任何别的线程操作的可能,所有临界资源都需要保护。
三、注意事项
①禁止多个线程同时操作同一个伪线程
②若伪线程执行函数的操作是比较耗时间或有可能挂起,则不建议使用伪线程。
③伪线程管理器创建失败,该进程模块必须对错误返回值进行处理。
④在系统初始化时,至少要添加一个伪线程,否则无限循环中没有可运行的伪线程会导致后续的伪线程添加失败。
⑤伪线程参数指针不能是临时变量,并且该变量释放前要取消所以使用该变量的伪线程。
⑥在运行过程要关闭套接字时,若该套接字有添加对应的伪线程,则需要将该伪线程从伪线程管理器中取消。
四、实现机制
①伪线程作为一种调度机制,内部是由select来进行各个伪线程之间的调度的。当select到某一个socket可读/写,则调度该socket相关的伪线程操作。
②伪线程内部维护了一个伪线程缓冲池,当一个伪线程执行完之后,并不将其立即释放,而是放入该缓冲池中,这样当下一次该伪线程请求添加时,只需直接从该缓冲池中取出即可。
③每一个伪线程操作执行完毕,如果需要伪线程调度器继续调度,则需要重新添加该伪线程。
五、常用API
struct rg_thread_master *rg_thread_master_create ();
void rg_thread_master_finish (struct rg_thread_master * master);
struct rg_thread *rg_thread_add_read (struct rg_thread_master *m, int (*func)(struct rg_thread *), void *arg, int fd);
struct rg_thread *rg_thread_add_write (struct rg_thread_master *m, int (*func)(struct rg_thread *), void *arg, int fd);
struct rg_thread *rg_thread_add_timer (struct rg_thread_master *m, int (*func)(struct rg_thread *), void *arg, long timer);
struct rg_thread *rg_thread_add_event (struct rg_thread_master *m, int (*func)(struct rg_thread *), void *arg, int val);
struct rg_thread *rg_thread_fetch (struct rg_thread_master *m, struct rg_thread *fetch);
void rg_thread_call (struct rg_thread *thread);