linux 多进程广播,linux 多线程消息广播

最近在工作中遇到了问题一个纠结问题:一个底层通用的模块,在应用层有许多线程使用。该模块大多数情况下都是正常的,模块出问题之后或基于其他考虑需要重启底层模块,底层重启了之后理论上是应用层需要释放当前资源,重新开始应用层业务。

为了实现该目标,当前以使用方式是:底层模块重启前调用每一个应用程接口,通知他们释放当前资源。但感觉这个设计有些缺陷:完全破坏了底层模块的封装完整性。

然后首先想到的是应用层,自己不停的检测底层模块的状态,但是觉得有点不太麻烦,需要一个while(1){check},有点低效

最后想到了tcp 中的组播思想,首先将需要监控底层模块的线程加入一个分组内,当底层模块状态需要发生改变时,给组内每个线程发送一个通知消息。应用线程接收到通知消息之后,释放当前资源,重新开始业务。

下面是这个线程组播的消息的源代码,源码仅仅是一个demo,用于阐述线程组播思想的框架,在实际引用中需要用户自己完善。

#include #include

#include

#include

#include

#define MAX 5

typedef struct{

pthread_t pid_th;

void (*sig_pro)(int);

}board_sig;

board_sig siglist[MAX];

void th1_sighandler(int signo)

{

pthread_t   tid = pthread_self();

printf("thread with pid:%lu receive signo:%d, I am th1 pro\n", tid, signo);

return;

}

void th2_sighandler(int signo)

{

pthread_t   tid = pthread_self();

printf("thread with pid:%lu receive signo:%d, I am th2 pro\n", tid, signo);

return;

}

void th3_sighandler(int signo)

{

pthread_t   tid = pthread_self();

printf("thread with pid:%lu receive signo:%d, I am th3 pro\n", tid, signo);

return;

}

void sighandler(int signo)

{

pthread_t   tid = pthread_self();

int i = 0;

for(i = 0; i < MAX; i++)

{

if(tid == siglist[i].pid_th)

{

siglist[i].sig_pro(signo);

}

}

}

void Init_User1Sig_Board(pthread_t pid_th, void (*sig_pro)(int))

{

int i = 0;

for(i = 0; i < MAX; i++)

{

if(siglist[i].pid_th == 0)

{

siglist[i].pid_th = pid_th;

siglist[i].sig_pro = sig_pro;

break;

}

}

}

User1Sig_Board_Pro()

{

int i = 0;

for(i = 0; i < MAX; i++)

{

if(siglist[i].pid_th != 0)

{

printf("i = %d, pid_th = %lu\n", i, siglist[i].pid_th);

pthread_kill(siglist[i].pid_th,SIGUSR1);

//usleep(1000);

}

}

}

void * thr1_fn(void *arg)

{

pthread_t   tid = pthread_self();

printf("thread 1 with tid:%lu\n", tid);

Init_User1Sig_Board(tid, th1_sighandler);

sleep(15);

return NULL;

}

void *thr2_fn(void *arg)

{

pthread_t       tid = pthread_self();

printf("thread 2 with tid:%lu\n", tid);

Init_User1Sig_Board(tid, th2_sighandler);

sleep(15);

return NULL;

}

void *thr3_fn(void *arg)

{

pthread_t   tid = pthread_self();

printf("thread 3 with tid:%lu\n", tid);

Init_User1Sig_Board(tid, th3_sighandler);

sleep(15);

return NULL;

}

int main(void)

{

int     rc, err;

pthread_t   thr1, thr2, thr3, thrm = pthread_self();

struct sigaction    action;

action.sa_flags = 0;

action.sa_handler = sighandler;

sigaction(SIGUSR1, &action, NULL);

printf("thread main with pid %lu\n",thrm);

err = pthread_create(&thr1, NULL, thr1_fn, NULL);

if (err != 0) {

printf("error in creating pthread:%d\t%s\n",err, strerror(rc));

exit(1);

}

/*  pthread_kill(thr1, SIGALRM);    send a SIGARLM signal to thr1 before thr2 set the signal handler, then the whole process will be terminated*/

err = pthread_create(&thr2, NULL, thr2_fn, NULL);

if (err != 0) {

printf("error in creating pthread:%d\t%s\n",err, strerror(rc));

exit(1);

}

err = pthread_create(&thr3, NULL, thr3_fn, NULL);

if (err != 0) {

printf("error in creating pthread:%d\t%s\n",err, strerror(rc));

exit(1);

}

sleep(10);

//内部产生的信号,只有指定的线程能收到,因此要向所有线程发送

User1Sig_Board_Pro();

pthread_join(thr1, NULL);   /*wait for the threads to complete.*/

pthread_join(thr2, NULL);

pthread_join(thr3, NULL);

printf("main ends\n");

return 0;

}

编译调试结果:

# gcc c.c -o c -lpthread # ./c thread main with pid 3075667648 thread 3 with tid:3058879296 thread 2 with tid:3067272000 thread 1 with tid:3075664704 i = 0, pid_th = 3058879296 i = 1, pid_th = 3067272000 i = 2, pid_th = 3075664704 thread with pid:3058879296 receive signo:10, I am th3 pro thread with pid:3067272000 receive signo:10, I am th2 pro thread with pid:3075664704 receive signo:10, I am th1 pro main ends

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值