atomic_bool值更新,其他进程看不到

2tr*_*ill 4 c struct c11

我有一个程序,有两个与共享内存通信的进程.在ctrl-c上我希望两个进程都退出.我正在使用一个atomic_bool名为stop 的变量来通知进程在设置为true时保持循环或退出.但是,当atomic_bool变量stop设置为true时,其他进程不会看到更改.这意味着它仍然打印出0而不是1,但是进行更改的过程显示1.那么为什么第二个进程看不到从false变为true?

Control-c不能用于杀死进程,因此请使用killall.

#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <stdbool.h>
#include <stdatomic.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <errno.h>

struct shared_map
{

    atomic_bool stop;

};

struct shared_map *map;

int compare_and_swap_loop(atomic_bool target, int value)
{
    /* Loop until we can succesfully update the the value. */
    while(1)
    {
        /* Grab a snapshot of the value that need to be updated. */
        bool snapshot = atomic_load(&target);

        if(atomic_compare_exchange_weak(&target, &snapshot, value) == true)
        {
            /* We succesfully updated the value let's exit this loop and return. */
            break;
        }
    }

   printf("result: %d\n", atomic_load(&target));

    return 0;
}

static void ctrlc_handler(int sig)
{
    compare_and_swap_loop(&map->stop, true);

    return;
}

void setup_signal_handler(void)
{
    (void) signal(SIGINT, ctrlc_handler);

    return;
}

static int create_shared(void **pointer, int size)
{
    *pointer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
    if(*pointer == MAP_FAILED)
    {
        printf("mmap: %s\n", strerror(errno));
        return -1;
    }

    return 0;
}

static void loop(void)
{
    /* Set up signal handler. */
    setup_signal_handler();

    /* Check if we should stop or continue running. */
    while(atomic_load(&map->stop) == false)
    {
        sleep(2);

        printf("map->stop: %d\n", atomic_load(&map->stop));
    }

    return;
}

int main(void)
{
    int rtrn;
    pid_t pid;

    rtrn = create_shared((void **)&map, sizeof(struct shared_map));
    if(rtrn < 0)
    {
        printf("Can't create shared memory\n");
        return -1;
    }

    atomic_init(&map->stop, false);

    pid = fork();
    if(pid == 0)
    {
        loop();

        _exit(0);
    }
    else if(pid > 0)
    {
        int status;

        waitpid(pid, &status, 0);

        return 0;
    }
    else
    {
        printf("fork: %s\n", strerror(errno));
        return -1;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

nos*_*nos 6

您将原子变量的副本传递给您的compare_and_swap_loop函数,这对您没有任何好处 - 您需要处理在您的进程之间共享的相同值.

你需要这样做:

int compare_and_swap_loop(atomic_bool *target, int value)
{
   /* Loop until we can succesfully update the the value. */
   while(1)
   {
    /* Grab a snapshot of the value that need to be updated. */
       bool snapshot = atomic_load(target);

       if(atomic_compare_exchange_weak(target, &snapshot, value) == true)
       {
        /* We succesfully updated the value let's exit this loop and return. */
        break;
       }
   }

   printf("result: %d\n", atomic_load(target));

   return 0;
}
Run Code Online (Sandbox Code Playgroud)