spx2 has asked for the wisdom of the Perl Monks concerning the following question:

i need to lock STDOUT so that nobody writes to it
or uses it except for me.if i do "lock STDOUT"
i get
Can't modify constant item in lock at /home/spx2/cod/scripturi_perl_teste/threads/diningphilosophers_lock.pl line 18, near "STDOUT;
so what could i lock to have the screen for myself
thank you

Replies are listed 'Best First'.
Re: locking STDOUT
by Corion (Patriarch) on Jun 04, 2007 at 10:53 UTC

    lock doesn't work the way you seem to think it does. Only few operating systems have mandatory file locking, and locking only works between processes, not within a single process.

    If you want to prevent other parts of your program from printing output to the screen, you will have to reopen STDOUT to something else:

    my $old_STDOUT = \*STDOUT; my $capture; open STDOUT, '>', \$capture or die "Couldn't do in-memory capture of program output: $!";

    If you have subprocesses that output to the screen, you will have to redirect or capture their output (via shell pipes or IPC::Open or IPC::Open3).

      so you suggest filtering all things 
      through a shell pipe...im not sure how
      i could use that to have lock-similar functionality.
      im into multithreading not multiprocesses.
      im thinking of making a separate
      
      my $buffer:shared=""; sub PRINT { lock $buffer; $buffer.=shift; } sub dump_on_screen { lock $buffer; print $buffer; $|++; $buffer=""; }
      and have a thread say...PRINT_THREAD that
      periodically prints stuff to the screen
      but in the order they happened in real-time
      
      my $pt=threads->new(\&PRINT_THREAD); sub PRINT_THREAD { dump_on_screen(); }
      i havent been clear enough in what i want to do actually, i have a multithreding app and i want to print stuff on the screen just as they happen. i want print to be atomic so thats why i want to lock the screen before i start doing anything. id like to get the order in wich threads

        i havent been clear enough in what i want to do actually, i have a multithreding app and i want to print stuff on the screen just as they happen. i want print to be atomic so thats why i want to lock the screen before i start doing anything. id like to get the order in wich threads

        In that case, I don't think you want to lock the screen but set STDOUT to be non-buffering. See the $| entry in perlvar or Suffering from Buffering.

        -derby

        Update: At the beginning of your script, I would set STDOUT to be non-buffering:

        select STDOUT; $| = 1;