Linux下实现多线程异步管道

50 篇文章 4 订阅

目录

架构

代码

相关阅读


​“最近在做F-Stack相关内容,F-Stack协议栈单线程独占异步轮询网卡,所以要求异步​。但是又有多线程需要利用F-Stack进行发包,并且发包ff_sendto需要由F-Stack线程调用,就这样引入了​此篇命题。”

架构

代码


/**

* 异步管道

* rongtao@sylincom.com

* 2020年8月4日11:11:03

*/


#include <stdio.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>

#define _GNU_SOURCE /* See feature_test_macros(7) */

#include <pthread.h>

#include <sys/epoll.h>

#include <string.h>


/* epoll最大event数 */

#define MAX_EVENTS 64


/* 管道两头的线程 */

static pthread_t tpipe_in1;

static pthread_t tpipe_in2;

static pthread_t tpipe_out;


/* 管道两头的FD */

static int pipe_fd[2] = {-1};


/* 管道两头的打开方式 */

static FILE *pipe_in_fp = NULL;

static FILE *pipe_out_fp = NULL;


/* epoll fd */

static int epoll_fd = -1;


/* epoll events */

static struct epoll_event epoll_evs[MAX_EVENTS];



/* 向管道发送数据,数据将从另一端输出 */

inline int mysendto(void *buf, size_t size) {

int n = write(fileno(pipe_in_fp), buf, size);

// printf("<< pipe << %s\n", buf);

}


/* 管道进口任务1 */

void * thread_pipe_in(void*arg) {


char threadname[16];

unsigned long int tid = pthread_self();

pthread_getname_np(pthread_self(), threadname, 16);


while(1) {

usleep(tid%521233);

char buf[100] = {0};

sprintf(buf, "I'm thread %s-%lu.", threadname, tid);

mysendto(buf, strlen(buf));

}

}


/* 管道出口任务主循环 */

int pipe_out_loop(void*arg) {


static char buffer[1024] = {0};

int nr_events = 0, iev;


nr_events = epoll_wait(epoll_fd, epoll_evs, MAX_EVENTS, -1);


for(iev = 0; iev < nr_events; iev ++) {

if(epoll_evs[iev].data.fd == fileno(pipe_out_fp)

&& epoll_evs[iev].events&EPOLLIN) {


int n = read(fileno(pipe_out_fp), buffer, 1024);

printf(">> pipe >> %s\n", buffer);


}

}


}


/* 管道出口任务 */

void * thread_pipe_out(void*arg) {


while(1) {

/* 该loop类比于fstack的ff_run(loop, NULL) */

pipe_out_loop(NULL);

}

}


/* 初始化管道 */

void pipe_initial() {


pipe(pipe_fd);


/* 打开管道两端 */

pipe_in_fp = fdopen(pipe_fd[1], "w");

pipe_out_fp = fdopen(pipe_fd[0], "r");


}


/* 启动任务 */

void thread_execute() {


pthread_create(&tpipe_in1, NULL, thread_pipe_in, NULL);

pthread_create(&tpipe_in2, NULL, thread_pipe_in, NULL);


pthread_create(&tpipe_out, NULL, thread_pipe_out, NULL);


pthread_setname_np(tpipe_in1, "pipe-in1");

pthread_setname_np(tpipe_in2, "pipe-in2");


pthread_setname_np(tpipe_out, "pipe-out");


}


/* 主进程loop */

void main_loop() {


while(1) {

sleep(1);

/* do nothing */

}

}


/* 初始化epoll */

void epoll_initial() {

epoll_fd = epoll_create(1);

struct epoll_event pipe_ev;

pipe_ev.data.fd = fileno(pipe_out_fp);

pipe_ev.events = EPOLLIN;

epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fileno(pipe_out_fp), &pipe_ev);

}


/* 主函数 */

int main () {


pipe_initial();/* 初始化管道 */


epoll_initial();/* 初始化epoll */


thread_execute();/* 开始执行任务 */


main_loop();/*主循环,由主进程执行 */

}

相关阅读

Linux异步管道多线程速率测试Linux异步管道多线程速率测试_RToax-CSDN博客

 (72条消息) Linux下实现多线程异步管道_RToax-CSDN博客_linux多线程 管道

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值