1

2つの条件(C1とC2)のスクリプトがあります。ユーザーがログインするたびに、User1(U1)がC1、U2からC2、U3からC1、U4に割り当てられるように、厳密なカウンターバランス(ランダム割り当てではない)を使用して、このユーザーをこれら2つの条件のいずれかに割り当てます。 C2などへ。

これを行う最も簡単な方法は何ですか?

今、私はこれを行うことを考えていました:

my $cond;
my $out_cfile = "cfile.txt"; #intial value printed in the file is 1
open(CFILE, "+<", $out_cfile) or die "cannot open $out_cfile";
flock(CFILE, 2);
my $cdata = <CFILE>;
my $last = (substr $cdata,-1,1); #get the latest printed value
if ($last == 1) {$cond = 1; print CFILE "2";}
if ($last == 2) {$cond = 2; print CFILE "1";}
close(CFILE);

print "my condition is: $cond";

出力ファイルを開いて印刷せずにこれを行う方法はありますか?

4

3 に答える 3

0

私はタイドハッシュを使用しますが、スレッドセーフが必要な場合は、何らかの形式のミューテックス(おそらくセマフォ)を実装する必要があります。

于 2012-12-17T19:33:47.367 に答える
0

最も簡単な方法は、lock警告:テストされていませんが、このようなものが機能するはずです)を使用することです。

use strict;
use warnings;
use threads;
use threads::shared;
use Thread::Queue;

my $num_users_logged_in :shared = 1;

my $num_watcher_threads = 1; #it may make sense to make this larger, maybe not. 

my @users = (); #populate array of users that are logging in.

my $queue = Thread::Queue->new;

$queue->enqueue(@users);

my @threads = ();

foreach(1..$num_watcher_threads)
{
  push @threads, threads->create(\&log_in);
}

# NOTE: If you ever want this program to stop, 
# then you'll have to enqueue some undefs (one for each thread).

# Waiting for each of the threads to finish.
# If you don't want to do this, then detach() instead
$_->join() foreach(@threads);

#Do anything else that you want after all of the threads are done.

sub log_in
{
  #Threads will block until it grabs an undef in the queue
  while(my $user = $queue->dequeue)
  {
    #Do whatever you need to do before locking the variable.
    {
      lock $num_users_logged_in;
      #Other threads will block until we're done with this block of code.

      #Assign conditions based upon the parity of $num_users_logged_in
      #And do whatever else you need for that particular user

      $num_users_logged_in++;
    }
  }
}
于 2012-12-17T19:34:49.443 に答える
0

/tmpディレクトリやファイルがまだ存在しない場合はどこにでもファイルを作成することの苦痛を本当に理解していませんが、memcached代わりに使用することができます。

use Cache::Memcached qw( );

my $memd = Cache::Memcached->new({
   server    => [ '127.0.0.1:11211' ],
   namespace => 'app_name:',
});

my $val = $memd->incr('counter');
if ($val % 2) {
   ...
} else {
   ...
}

incr競合状態を回避するために、アトミックにインクリメントおよびフェッチします(したがって、コードのように安全です)。

于 2012-12-18T18:12:26.600 に答える