简体   繁体   中英

Multiple processes without lock

I am working on a project in my OS class, we are working in C and we haven't learned about locks yet for congruent programming.

I have an array that every process shares and a pointer to that array that every process shares.

We have one parent process that is going to be forking 1-10 children depending on an argument given to a function. The idea of the project is to convert .png, .bmp, and .gif images to .jpg the type of image a process converts is based on their pid.

if pid mod 3 = 0 convert .png
if pid mod 3 = 1 convert .bmp
if pid mod 3 = 2 convert .gif

We have an array that we constructed that has all files that need to be converted, all processes share this array And we are thinking about having 3 int pointers bmpptr, pngptr, gifptr.

and we have these lines in the child process

if getpid() mod 3 = 0
  temp = *pngptr++
else if getpid() mod 3 = 1
  temp = *bmpptr++
else 
  temp = *gifptr++ 

The question I have is can the OS take control away from the process on one of the children on this single line of code so that two children would have the same temp var because it took control after temp gets assigned, but before the increment occurs?

temp = *<ptr>++

I'm thinking yes, but is there any good way around this without using locks?

Forked children processes typically get a copy of their parent's memory. One child updating one of these pointers should have no effect on any other child's version of that pointer.

One way to accomplish something similar to what you are after is that while the parent is forking the children, it is inspecting their pid()'s after each fork and then updating these pointers as you do before the next fork().

void forkChildren(unsigned num)
{
  while (num--)
  {
    pid_t ret = fork();

    if (0 == ret) 
    {
      /* child process */

      char *tmp;

      switch (getpid() % 3)
      {
      case 0: tmp = *pngptr; break;
      case 1: tmp = *bmpptr; break;
      case 2: tmp = *gifptr; break;     
      }

      doChild(tmp);
      exit(0);
    } 
    else if (-1 != ret) 
    {
      /* parent process */

      switch (ret % 3)
      {
      case 0: pngptr++; break;
      case 1: bmpptr++; break;
      case 2: gifptr++; break;     
      }
    }
    else
      perror("fork failed");
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM