简单的多线程数据传输

网友投稿 287 2022-08-31

简单的多线程数据传输

说明

为创建一份小型的工程代码,自己想出一个简单的数据传输任务。 主进程创建四个线程,st1,st2,st3,rt,让前三个线程向最后一个线程灌包,最后一个线程接收数据包。 目的IP: 10.21.100.152 目的端口:9001 各个进程被创建后立即进行相应的工作,灌包或者收包。rt接收到数据包后打印出相应的信息。

makefile

工程文件的编译会接触到makefile,下面是总结的常用的makfile变量

变量

意义

$*

不包含扩展名的目标文件名称。

$+

所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。

$<

第一个依赖文件的名称。

$?

所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。

$@

目标的完整名称。

$^

所有的依赖文件,以空格分开,不包含重复的依赖文件。

$%

如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称为 mytarget.so(image.o),则 $@ 为 mytarget.so,而 $% 为 image.o。

AR

静态库打开包命令的名字,default:ar

ARFLAGS

静态库打开包命令的选项,default:rv

AS

汇编器的名字,default: as

ASFLAGS

汇编器的选项

CC

C编译器的名字,default: cc

CFLAGS

C编译器的选项

CXX

c++编译器的名字,default: g++

CXXFLAGS

c++编译器的选项

CPP

C预处理器的名字,default: $(CC) -E

CPPFLAGS

C预处理器的选项

LD

链接器的名字, default: 1d

LDFLAGS

链接器的选项

TARGET_ARCH

和目标平台相关的命令行选项

OUTPUT_OPTION

输出的命令行选项,default: -o $@

LINK.o

把.o文件链接在一起的命令行,default: $(CC) $(LDFLAGS) $(TARGET_ARCH)

LINK.c

把 .c 文件链接在一起的命令行, default: $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

LINK.cc

把 .cc 文件(C++源文件)链接在一起的命令行, default: $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

COMPILE.c

编译.c文件的命令行, default: $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

COMPILE.cc

编译 .cc 文件的命令行, default: $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

RANLIB

静态库的符号索引表

CROSS_COMPILE

编译器前缀

ARCH

CPU体系结构

另外一些可能用到的: STRIP: 去空格函数,去除开头和结尾出现的空字符 addprefix: 加前缀函数

$(addprefix , , ...)该函数将前缀 加到各个 的前面去。

代码结构

图中的.a文件和.d文件是编译后产生的。

.a文件是静态库文件,.d文件为源文件的依赖关系的完整规则。

code

common.h

#ifndef COMMON_H#define COMMON_H#include #include #include #include #include #include #include #include #include #include #include #include #include #define Len 20#define Num 10#define TASK_JOIN 1typedef unsigned char UINT8;typedef unsigned short UINT16;typedef int INT32;typedef struct msg{ UINT8 context[Num][Len];}Msg;pthread_t g_st1;pthread_t g_st2;pthread_t g_st3;pthread_t g_rt;int g_rt_recv_sock;struct sockaddr_in g_sendto;struct sockaddr_in g_recvfr;pthread_t create_pthread(INT32 prior, INT32 policy, INT32 state, void *fn, void *args_p);void *msg_malloc(UINT8 dex);void handler(int arg);int recv_sock_set(UINT16 PORT);struct sockaddr_in send_sock_set(char *IP, UINT16 PORT);#endif

common.c

#include "../inc/common.h"pthread_t create_pthread(INT32 prior, INT32 policy, INT32 state, void *fn, void *args_p){ pthread_attr_t attr; struct sched_param param; pthread_t taskid; INT32 ret; pthread_attr_init(&attr); pthread_attr_setschedpolicy(&attr, policy); /* 调度策略 */ param.sched_priority = prior; /* 设定优先级 */ pthread_attr_setschedparam(&attr, ¶m); /* PTHREAD_SCOPE_SYSTEM: kernel level thread, PTHREAD_SCOPE_PROCESS: user level thread */ /* 设置线程优先级的有效范围,PTHREAD_SCOPE_SYSTEM表示和系统中所有线程竞争 */ pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); /* PTHREAD_CREATE_DETACHED : detachstate thread 相分离线程 PTHREAD_CREATE_JOINABLE : joinable thread 可会合线程 */ if (state != 1) { pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); } /* PTHREAD_INHERIT_SCHED: inherit father thread's attr * PTHREAD_EXPLICIT_SCHED: use pthread_create() attr */ pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED); if ((ret = pthread_create(&taskid, &attr, fn, args_p)) != 0) { printf("fail to create pthread: ret=%d\n", ret); /* 取得用户的识别码,等于0则是root */ if(getuid() != 0){ printf("Please run app with root user\n"); } return -1; } else{ pthread_attr_destroy(&attr); return taskid; }}void *msg_malloc(UINT8 dex){ void *mem = malloc(sizeof(Msg)); Msg *g_msg = (Msg *)mem; int i; for(i=0;icontext[i],str); } return mem;}int recv_sock_set(UINT16 PORT){ int sock_fd = socket(AF_INET,SOCK_DGRAM,0); if(sock_fd == -1){ perror("socket "); exit(1); } struct sockaddr_in serv; bzero(&serv,sizeof(serv)); serv.sin_family = AF_INET; serv.sin_addr.s_addr = htonl(INADDR_ANY); //inet_addr(""); serv.sin_port = htons(PORT); if(bind(sock_fd,(struct sockaddr *)&serv, sizeof(serv)) == -1){ perror("bind "); exit(1); } return sock_fd;}struct sockaddr_in send_sock_set(char *IP, UINT16 PORT){ struct sockaddr_in send; bzero(&send,sizeof(send)); send.sin_family = AF_INET; send.sin_addr.s_addr = inet_addr(IP); send.sin_port = htons(PORT); return send;}void handler(int arg){ printf("ctrl c finish process.\n"); exit(0);}

main.c

#include "../inc/common.h"extern void *st1_thread_run(void *args);extern void *st2_thread_run(void *args);extern void *st3_thread_run(void *args);extern void *rt_thread_run(void *args);int main(){ printf("main process start.\n"); signal(SIGINT,handler); pthread_t st1, st2, st3, st4; char *sendto_IP = "10.21.100.152"; UINT16 PORT = 9000; g_sendto = send_sock_set(sendto_IP,PORT); g_rt = create_pthread(90,SCHED_FIFO, TASK_JOIN,rt_thread_run,"rt_thread_run"); /*在本地实验,如果三个发送数据的线程优先级是一样的,那么第一个线程在后期争夺资源不如另外两个,所以将其调高了一点*/ g_st1 = create_pthread(91,SCHED_FIFO, TASK_JOIN,st1_thread_run,"st1_thread_run"); g_st2 = create_pthread(92,SCHED_FIFO, TASK_JOIN,st2_thread_run,"st2_thread_run"); g_st3 = create_pthread(92,SCHED_FIFO, TASK_JOIN,st3_thread_run,"st3_thread_run"); if(g_rt > 0)pthread_join(g_rt, NULL); /* 等待st1线程结束 */ else printf("create thread rt failed.\n"); exit(0);}

rt.c

#include "../inc/common.h"void *rt_thread_run(void *args){ printf("rt thread start work!\n"); g_rt_recv_sock = recv_sock_set(9000); void *get_msg = malloc(Len); if(get_msg == NULL){ perror("get_msg malloc "); exit(1); } while(1){ int recv_len = sizeof(g_recvfr); int ret = recvfrom(g_rt_recv_sock,get_msg,Len,0,(struct sockaddr*)&g_recvfr,&recv_len); if(ret > 0){ printf("%s\n",(char *)get_msg); } else printf("here is no data.\n"); } if(get_msg) free(get_msg); return

st1.c

#include "../inc/common.h"void *st1_thread_run(void *args){ printf("st1 thread start work!\n"); //void *msg = msg_malloc((UINT8)1); char *get_msg = "this is st1 msg."; g_st1 = socket(AF_INET,SOCK_DGRAM,0); if(g_st1 == -1){ perror("socket "); exit(1); } while(1){ int i; /* Msg *send_msg = (Msg *)msg; for(i=0;icontext[i],strlen(send_msg->context[i]),0, (struct sockaddr *)&g_sendto,sizeof(g_sendto)); }*/ int ret = sendto(g_st1,get_msg,strlen(get_msg),0,(struct sockaddr *)&g_sendto,sizeof(g_sendto)); if(ret <= 0){ perror("st1 send to "); } sleep(1); //send_msg = NULL; } return

st2.c

#include "../inc/common.h"void *st2_thread_run(void *args){ printf("st2 thread start work!\n"); char *get_msg = "this is st2 msg."; g_st2 = socket(AF_INET,SOCK_DGRAM,0); if(g_st2 == -1){ perror("socket "); exit(1); } while(1){ int i; int ret = sendto(g_st2,get_msg,strlen(get_msg),0,(struct sockaddr *)&g_sendto, sizeof(g_sendto)); if(ret <= 0){ perror("st2 send to "); } sleep(1); } return

st3.c

#include "../inc/common.h"void *st3_thread_run(void *args){ printf("st3 thread start work!\n"); char *get_msg = "this is st3 msg."; g_st3 = socket(AF_INET,SOCK_DGRAM,0); if(g_st3 == -1){ perror("socket "); exit(1); } while(1){ int i; int ret = sendto(g_st3,get_msg,strlen(get_msg),0,(struct sockaddr *)&g_sendto, sizeof(g_sendto)); if(ret <= 0){ perror("st3 send to "); } sleep(1); } return

/pthread_data_transfer/makefile

PWD := $(shell pwd)IncDir := $(PWD)/../incINCLUDE_H_DIR := $(IncDir)DEBUG := -gMAIN := $(PWD)/srcMAIN_OBJ := $(MAIN)/*.o.PHONY:all all:lib $(CC) -o main $(MAIN_OBJ) -lm -lpthread -lrt .PHONY:liblib: $(MAKE) -C $(MAIN).PHONY:cleanclean:

/pthread_data_transfer/src/makefile

# source fileC_SOURCE := $(shell find -name '*.c')#Get object file generated by C source fileC_OBJS := $(subst .c,.o,$(C_SOURCE))#Get dependent file DEPS := $(subst .o,.d,$(C_OBJS)).PHONY:allall:$(C_OBJS)$(C_OBJS):%.o:%.c $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ifneq "$(MAKECMDGOALS)" "clean"-include $(DEPS)endif%.d:%.c $(CC) -M $(CFLAGS) $< > $@.$$$$;\ sed 's,$(subst .c,.o,$(notdir $<)),$(subst .c,.o,$<) $@,g' < $@.$$$$ > $@;\ rm -f $@.$$$$.PHONY:cleanclean:

得到的结果 (用root: ./main > read):

main process start.rt thread start work!st1 thread start work!this is st1 msg.st2 thread start work!this is st2 msg.st3 thread start work!this is st3 msg.this is st2 msg.this is st3 msg.this is st1 msg.this is st2 msg.this is st3 msg.this is st1 msg.this is st3 msg.this is st2 msg.this is st1 msg.this is st3 msg.this is st2 msg.this is

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:文案君:被甲方支配的恐惧,连大导贾樟柯都体验过!
下一篇:shell编程 (2) —— 基础
相关文章

 发表评论

暂时没有评论,来抢沙发吧~