Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly does "lock" do in Perl?

Tags:

perl

I was writing a Perl script and noticed that my editor highlighted the word "lock." I was curious so I looked up what "lock" does in Perl and have been unable to find a straightforward answer (at least not one that I could fully understand).

This is the best answer I found: http://perldoc.perl.org/functions/lock.html


ex: lock THING

"places an advisory lock on a shared variable or referenced object contained in THING until the lock goes out of scope."


What exactly does this mean? The "lock" function isn't used to lock files because everything I have read says to use "flock" for that, so what is "lock" used for? Does it have to do with threading and making sure multiple processes running at the same time don't bump into each other?

like image 383
tjwrona1992 Avatar asked Aug 29 '14 16:08

tjwrona1992


People also ask

Why lock is used in threading?

A lock allows you to force multiple threads to access a resource one at a time, rather than all of them trying to access the resource simultaneously. As you note, usually you do want threads to execute simultaneously.

How do I lock a file in Perl?

File locking can be done, in Perl, with the flock command. flock() accepts two parameters. The first one is the filehandle. The second argument indicates the locking operation required.


2 Answers

It's primary purpose is for multithreading. It locks a shared variable, such that if any other thread tries to lock it, then the lock call will block until it is released.

To illustrate:

#!/usr/bin/perl
use strict;
use warnings;

use threads;
use threads::shared;

my $lock_var : shared;

sub worker_thread {
    print threads -> self -> tid(). ": Waiting for lock\n";
    lock ( $lock_var );
    print threads -> self -> tid(). ": got lock, doing some pretend code\n";
    sleep rand(10);
    #lock released when out of scope.
}

for ( 1..10 ) {
    threads -> create ( \&worker_thread );
}

foreach my $thr ( threads -> list ) {
    $thr -> join();
}

You can either use it for resource control, to create a mutual exclusion, or you can use it to lock e.g. a hash when you want to update it without another thread doing so at the same time.

You should note though - the lock is not enforced. You can still modify the shared variable despite the lock. It's only the lock function call that'll test if the variable is currently unlocked.

When you're doing a variable manipulation, it's important to use lock. Any test where you read->change->write you can create a race condition if you don't lock - you cannot be certain that between the read and write, another thread won't do the same.

You may want to also look at Thread::Semaphore which does something similar.

like image 181
Sobrique Avatar answered Oct 23 '22 17:10

Sobrique


In terms of file locking, of which you appear to have some knowledge:

  • When you do flock($fh, LOCK_EX) or die $!;, it'll block until it obtains a lock on that file. No two handles can hold a lock on that file at the same time.

  • When you do lock $var;, it'll block until it obtains a lock on that shared variable. No two threads can hold a lock on that shared variable at the same time.

As you can see, both provide a means of providing mutual access to some arbitrary resources.

Notes:

  • Shared variables exist within a process, so lock $var; only provides synchronicity within a process. But it also means it doesn't need to use any named external resources (e.g. a file).
like image 21
ikegami Avatar answered Oct 23 '22 16:10

ikegami