如何在共享内存派生进程中使用互斥锁? [英] How to use mutexes in a shared memory forked process?

查看:186
本文介绍了如何在共享内存派生进程中使用互斥锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个多进程程序之间共享一个计数器变量,该程序使用fork()调用创建进程.我正在使用以下代码创建一个用于存储计数器的共享内存,并且每个进程都可以对其进行访问和递增.

I'm sharing a counter variable between a multi-process program, where processes are created using the fork() call. I'm using the following code to create a shared memory where the counter is stored, and can be accessed and incremented by each process.

这是主父线程中的线程创建机制

This is the thread creation mechanism in the main parent thread

void createSHM()
{
int key = SHMKEY;
int *shm;

if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
    perror("shmget");
    exit(1);
}

if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
    perror("shmat");
    exit(1);
}
*shm=0
}

这是在每个派生进程中调用的函数,用于获取计数器的值并将其递增.

and this is the function called in each of the forked processes to get the value of the counter, and increment it.

int attachSHMandIncrement()
{
int key = SHMKEY;
int *shm;

if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
    perror("shmget");
    exit(1);
}

if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
    perror("shmat");
    exit(1);
}
*shm++;
return *shm;
}

  1. 我不确定此实现是否不受种族限制?任何人都可以发表评论,如果不是,那么举个例子,说明如何使其免于种族歧视?

  1. I'm not sure if this implementation is race free? Can anyone comment on if it is, and if not, an example of how this can be made race free?

鉴于这些事实是分叉的进程,将在派生时继承内存.我有什么要记住的吗?我之前是在完全独立的流程中完成此操作的,但在这里我可能必须在分叉的流程中执行此操作.

Given the fact that these are forked processes and will inherit the memory at the time of fork. Is there anything I should keep in mind? I've done this before in totally separate processes but here I might have to do it in forked processes.

推荐答案

由于您没有任何互斥锁,因此没有什么可以阻止两个进程尝试同时增加计数器,并且通常由于int的增加不是原子的,这是直接的比赛条件.除了递增竞赛外,例程还会递增,然后读取该值,该值也不是原子的,因此受竞赛影响.

Since you don't have any mutexes, there's nothing to stop two processes from trying to increment the counter simultaneously, and since increment of an int is generally not atomic, this is an immediate race condition. Over and above the increment race, the routine increments and then reads the value, which is also not atomic, so subject to races.

为了避免种族,您需要某种互斥体.您可以使用信号灯,也可以在共享内存中使用pthread互斥锁(如果有pthreads可用).或者,您可以使用文件锁,也可以编写自己的原子程序集例程并调用它们.如果您使用的是C11,甚至可以使用stdatomic.h中的内容.很多可能的选择.

In order to avoid races, you need some sort of mutex. You could use a semaphore, or you might be able to use a pthread mutex in shared memory (if you have pthreads available). Alternately you may be able use file locks, or you could write your own atomic assembly routines and call them. If you're using C11, you could even use the stuff in stdatomic.h. Lots of possible choices.

修改

您可以在竞速操作周围包裹一个互斥体,以避免在增量函数末尾出现竞态条件:

You can wrap a mutex around the racing operations to avoid the race condition at the end of your increment function:

    struct sembuf sem_ops = { 0, -1, SEM_UNDO };
    semop(semid, &sem_ops, 1);
    *shm++;
    rv = *shm;
    sem_ops.sem_op = 1;
    semop(semid, &sem_ops, 1);
    return rv;
}

通常,您只需在每个进程中附加一次共享内存(并在一个进程中创建一次),然后使用它,而不必重复附加和分离它.同样,您将创建并初始化您的互斥锁一次,然后使用它们.

Generally, you'll just attach the shared memory once in each process (and create it once in one process), and then just use it, without repeatedly attaching and detaching it. Similarly, you'll create and initialize your mutexes once, and then use them.

这篇关于如何在共享内存派生进程中使用互斥锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆