use strict; use warnings; use threads; use threads::shared; use Time::HiRes qw( sleep time ); use Net::SNMPTrapd; use MCE::Flow; use MCE::Queue; my $tid = 0; sub CLONE { $tid = threads->tid(); } my $snmptrapd = Net::SNMPTrapd->new( ReusePort => 1 ); my $max_workers = 30; my $count : shared = 0; my $start : shared; MCE::Flow::init { user_output => sub { print {*STDOUT} $_[0]; }, user_error => sub { print {*STDERR} $_[0]; }, }; mce_flow { max_workers => $max_workers }, \&server; printf {*STDERR} "duration: %0.03f seconds\n", time - $start; exit(0); sub server { my $done = 0; while ( 1 ) { my $trap; { lock $count; $start = time unless $start; $trap = $snmptrapd->get_trap(); $done = 1 if ( ++$count > 10000 - $max_workers ); } if ( !defined $trap ) { MCE->printf(\*STDERR, "$0: %s\n", Net::SNMPTrapd->error()); next; } elsif ( $trap == 0 ) { next; } $trap->process_trap(); MCE->printf( "[%02d] %s\t%i\t%i\t%s\n", $tid, $trap->remoteaddr, $trap->remoteport, $trap->version, $trap->community ); last if $done; sleep 0.004; } }