linux多核单进程,Linux的在多核处理器3个处理(每个进程在不同的核心上运行)之间共享存储器/ SMP...

我想同步三种不同的过程,所以我想使用在进程之间共享内存。所以我从一个进程中分出了两个孩子,并在创建孩子之前创建了共享内存段。 我的意图是在不同的内核中运行子进程和父进程以使其并行执行。所以我使用亲和力控制来分配相应的CPU。这两个孩子都将在无限期等待while循环(在分配的同一个CPU上使用),直到它通过共享内存从父级获取触发器。所以当父母写入一些特定的字符/字符串时,孩子应该出来循环并开始执行其余的代码。

问题:

的变量“SHM”即共享内存的变化是不是子进程可见,从不出来while循环。

一些判断:

我觉得这个问题是因为它不被无效并提出了处理移动到特定内核后脏的L2缓存。所以核心仍然指向共享内存的旧值。只有当优化级别超过“0”时才会发生这种情况,即O2。当我强迫它到O0时,那么问题就看不到了。我对Linux内核和处理器本身的缓存背景不太了解。所以我暂时修改了代码,以便使用“volatile”从RAM中引用变量来摆脱这个问题。

实施例:

要查看真实这个问题,我已附加示例代码,其不与在“目的”说明。

我的问题:

这是预期的结果?

因此Linux不会在不同的CPU内核之间共享运行 的进程之间的内存吗?

至少AFAIK,内核总是会在相同内核中调度相同类型的进程,所以很难在不强制进程转移到其他内核的情况下实现这种情况。

/*

* Compilation commands:

* gcc -Wall -Wextra -O2 -o ./bin/share ./share.c

* - Optimization enabled, "volatile" is mandatory

* - Without "volatile" child1 and child2 indefinite loop

*

* gcc -Wall -Wextra -O0 -o ./bin/share ./share.c

* - Problem not seen

*

* Root cause of the problem is L2 cache, as it is private to core

*/

/* Linux includes */

#define _GNU_SOURCE

#include

#include

#include

#include

#include

#include

#include

/* Library includes */

#include

#include

int main(void) {

int rc;

int shmid;

int no_cpu;

/* volatile char *shm = NULL; <== uncomment to get rid of the problem */

char *shm = NULL;

cpu_set_t cpu;

size_t size = 10;

pid_t child1, child2;

no_cpu = sysconf(_SC_NPROCESSORS_ONLN);

if(no_cpu < 3) {

printf("ERROR: Minimum 3 CPU cores required\n");

printf("If you have only two CPU's, adjust the CPU_SET accordingly\n");

return -1;

}

CPU_ZERO(&cpu);

shmid = shmget(getpid(), size, IPC_CREAT);

if(shmid < 0) {

perror("Fail to get shared memory");

return -1;

}

if((shm = shmat(shmid, NULL, 0)) == (char *)-1) {

perror("Fail to attach to shared memory");

return -1;

}

child1 = fork();

if(child1 == 0) {

child2 = fork();

if(child2 == 0) { /* Parent */

CPU_SET(0, &cpu); /* Run on CPU 0 */

rc = sched_setaffinity(getpid(), sizeof(cpu), &cpu);

if(rc != 0) {

printf("Unable to set affinity to [%d] parent\n", getpid());

kill(child1, SIGTERM);

kill(child2, SIGTERM);

waitpid(child1, NULL, 0);

waitpid(child2, NULL, 0);

return -1;

}

printf("[%d] parent running in [%d]\n", getpid(), sched_getcpu());

*shm = 'a';

waitpid(child1, NULL, 0);

waitpid(child2, NULL, 0);

shmdt((void *)shm);

}

else if(child2 > 0) { /* Kid 2 */

CPU_SET(1, &cpu); /* Run on CPU 1 */

rc = sched_setaffinity(getpid(), sizeof(cpu), &cpu);

if(rc != 0) {

printf("Unable to set affinity to [%d] child2\n", getpid());

return -1;

}

printf("[%d] child2 running in [%d]\n", getpid(), sched_getcpu());

while(*shm != 'a');

shmdt((void *)shm);

exit(0);

}

else {

printf("Fork failed\n");

kill(child1, SIGTERM);

waitpid(child1, NULL, 0);

return -1;

}

}

else if(child1 > 0) { /* Kid 1*/

CPU_SET(2, &cpu); /* Run on CPU 2 */

rc = sched_setaffinity(getpid(), sizeof(cpu), &cpu);

if(rc != 0) {

printf("Unable to set affinity to [%d] child1\n", getpid());

return -1;

}

printf("[%d] child1 running in [%d]\n", getpid(), sched_getcpu());

while(*shm != 'a');

shmdt((void *)shm);

exit(0);

}

else {

printf("Fork failed\n");

return -1;

}

return 0;

}

+2

为什么使用'mmap(...,MAP_SHARED,...)'会执行sysV共享内存?你为什么期望'getpid()'返回一个有效的sysV'key_t'?你甚至可以阅读任何你正在尝试使用的函数的单页手册页吗? –

+2

缓存管理是操作系统的问题。您可以确定L2(或任何其他级别)缓存没有问题。总是先找到你身边的错,而不是别人的错! –

+0

你真的不应该像这样使用共享内存进行同步。这是一个信号量或两个信号的理想场所。 –

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值