linux多核单进程,Linux的在多核处理器3个处理(每个进程在不同的核心上运行)之间共享存储器/ SMP...
我想同步三種不同的過程,所以我想使用在進程之間共享內存。所以我從一個進程中分出了兩個孩子,并在創(chuàng)建孩子之前創(chuàng)建了共享內存段。 我的意圖是在不同的內核中運行子進程和父進程以使其并行執(zhí)行。所以我使用親和力控制來分配相應的CPU。這兩個孩子都將在無限期等待while循環(huán)(在分配的同一個CPU上使用),直到它通過共享內存從父級獲取觸發(fā)器。所以當父母寫入一些特定的字符/字符串時,孩子應該出來循環(huán)并開始執(zhí)行其余的代碼。
問題:
的變量“SHM”即共享內存的變化是不是子進程可見,從不出來while循環(huán)。
一些判斷:
我覺得這個問題是因為它不被無效并提出了處理移動到特定內核后臟的L2緩存。所以核心仍然指向共享內存的舊值。只有當優(yōu)化級別超過“0”時才會發(fā)生這種情況,即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,...)'會執(zhí)行sysV共享內存?你為什么期望'getpid()'返回一個有效的sysV'key_t'?你甚至可以閱讀任何你正在嘗試使用的函數的單頁手冊頁嗎? –
+2
緩存管理是操作系統(tǒng)的問題。您可以確定L2(或任何其他級別)緩存沒有問題。總是先找到你身邊的錯,而不是別人的錯! –
+0
你真的不應該像這樣使用共享內存進行同步。這是一個信號量或兩個信號的理想場所。 –
總結
以上是生活随笔為你收集整理的linux多核单进程,Linux的在多核处理器3个处理(每个进程在不同的核心上运行)之间共享存储器/ SMP...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 按月累计求和,SQL Cu
- 下一篇: linux 内核load addr,li