Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 635215
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T20:22:49+00:00 2026-05-13T20:22:49+00:00

I have a need to upgrade a Perl CGI script where the users must

  • 0

I have a need to upgrade a Perl CGI script where the users must complete 3 steps. After they finish each step, the script is logging which step the user completed. Having a record of this is important so we can prove to the user that they only finished step one and didn’t complete all three steps, for example.

Right now, the script is creating 1 log file for each instance of the CGI script. So if UserA does step 1, then UserB does step 1, then step 2, then step 3 – and then UserA finishes step 2 and step 3, the order of the log files would be.

LogFile.UserA.Step1
LogFile.UserB.Step1
LogFile.UserB.Step2
LogFile.UserB.Step3
LogFile.UserA.Step2
LogFile.UserA.Step3

The log files are named with the current timestamp, a random number, and the process PID.

This works fine to prevent the same file from getting written to more than once, but the directory quickly gets thousands of files (each file contains just a few bytes in it). There is a process to rotate and compress these logs, but it has fallen upon me to make it so the script logs to just one file a day to reduce the number of log files being created.

Basically, the log file will have the current date in the file name, and anytime the CGI script needs to write to the log, it will append to the one log file for that day, regardless of the user or what step they are on.

Nothing will need to be reading the log file – the only thing that will happen to it is an append by the CGI script. The log rotation will run on log files that are 7 days or older.

My question is, what is the best way to handle the concurrent appends to this log file? Do I need to lock it before appending? I found this page on Perl Monks that seems to indicate that “when multiple processes are writing to the same file, and all of them have the file opened for appending, data shall not be overwritten.”

I’ve learned that just because it can be done doesn’t mean that I should, but in this case, what is the safest, best practice way to do this?

Summary:

  • Concurrent appends to the same file
  • Each append to the file is just one line, less than 50 characters
  • Order does not matter

Thanks!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T20:22:49+00:00Added an answer on May 13, 2026 at 8:22 pm

    Yes, use flock.

    An example program is below, beginning with typical front matter:

    #! /usr/bin/perl
    
    use warnings;
    use strict;
    
    use Fcntl qw/ :flock /;
    

    Then we specify the path to the log and the number of clients that will run:

    my $log = "/tmp/my.log";
    my $clients = 10;
    

    To log a message, open the file in append mode so all writes automatically go at the end. Then call flock to wait our turn on having exclusive access to the log. Once we’re up, write the message and close the handle, which automatically releases the lock.

    sub log_step {
      my($msg) = @_;
    
      open my $fh, ">>", $log or die  "$0 [$$]: open: $!";
      flock $fh, LOCK_EX      or die  "$0 [$$]: flock: $!";
      print $fh "$msg\n"      or die  "$0 [$$]: write: $!";
      close $fh               or warn "$0 [$$]: close: $!";
    }
    

    Now fork off $clients child processes to go through all three steps with random intervals between:

    my %kids;
    my $id = "A";
    for (1 .. $clients) {
      my $pid = fork;
      die "$0: fork: $!" unless defined $pid;
    
      if ($pid) {
        ++$kids{$pid};
        print "$0: forked $pid\n";
      }
      else {
        my $user = "User" . $id;
        log_step "$user: Step 1";
        sleep rand 3;
        log_step "$user: Step 2";
        sleep rand 3;
        log_step "$user: Step 3";
        exit 0;
      }
    
      ++$id;
    }
    

    Don’t forget to wait on all the children to exit:

    print "$0: reaping children...\n";
    while (keys %kids) {
      my $pid = waitpid -1, 0;
      last if $pid == -1;
    
      warn "$0: unexpected kid $pid" unless $kids{$pid};
      delete $kids{$pid};
    }
    
    warn "$0: still running: ", join(", " => keys %kids), "\n"
      if keys %kids;
    
    print "$0: done!\n", `cat $log`;
    

    Sample output:

    [...]
    ./prog.pl: reaping children...
    ./prog.pl: done!
    UserA: Step 1
    UserB: Step 1
    UserC: Step 1
    UserC: Step 2
    UserC: Step 3
    UserD: Step 1
    UserE: Step 1
    UserF: Step 1
    UserG: Step 1
    UserH: Step 1
    UserI: Step 1
    UserJ: Step 1
    UserD: Step 2
    UserD: Step 3
    UserF: Step 2
    UserG: Step 2
    UserH: Step 2
    UserI: Step 2
    UserI: Step 3
    UserB: Step 2
    UserA: Step 2
    UserA: Step 3
    UserE: Step 2
    UserF: Step 3
    UserG: Step 3
    UserJ: Step 2
    UserJ: Step 3
    UserE: Step 3
    UserH: Step 3
    UserB: Step 3

    Keep in mind that the order will be different from run to run.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 403k
  • Answers 403k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Jeff Atwood wrote an article on Properties vs Public Variables… May 15, 2026 at 5:15 am
  • Editorial Team
    Editorial Team added an answer typically, when you do async IO, your protocol should support… May 15, 2026 at 5:15 am
  • Editorial Team
    Editorial Team added an answer There is no way to do such a thing. The… May 15, 2026 at 5:15 am

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.