16 바이트의 공유 파일을 생성하는 프로그램을 만들고 나서 매 초마다 각 바이트의 값을 보여주는 실험을하고 있습니다.이상한 mmap 동작
프로그램이 실행되는 동안 파일을 변경하고 프로그램이 변경 사항을 인식하도록하고 싶습니다.
프로그램은 파일에 실제로 쓰는 메모리에 쓰는 것처럼 보입니다. 하지만 런타임에 파일을 수정하면 파일이 변경 되더라도 이전 값을 계속 사용하고 파일이 업데이트되지 않습니다.
다음은 변경 사항을 인식하지 못하는 버전입니다.
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
// | bag of global state.
struct {
uint8_t *state;
char *filename;
int length;
} global = {
(uint8_t *)0,
"state.bin",
16
};
// | clean up when ctrl-c is pressed.
static void onSIGINT(int unused)
{
puts("caught SIGINT; cleaning up.");
munmap(global.state, global.length);
unlink(global.filename);
exit(0);
}
// | display each byte of global shared memory
static void inspect()
{
int i;
for (i = 0; i < global.length; ++i) {
printf("state[%d] = %d.\n", i, global.state[i]);
}
}
int main(int argc, char **argv)
{
/* anonymous scope: initialize shared memory */
{
// | mmap arguments
void *addr = (void *)0;
int prot = PROT_READ | PROT_WRITE;
int flags = MAP_SHARED;
int offset = 0;
int fd = open(global.filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
// | initialize memory to 16 zerod out bytes.
uint8_t dummy[16];
memset(&dummy, 0, global.length);
write(fd, dummy, global.length);
global.state = (uint8_t *)mmap (
addr,
global.length,
prot,
flags,
fd,
offset
);
if (global.state == MAP_FAILED) {
close(fd);
perror("could not create map.\n");
unlink(global.filename);
}
}
signal(SIGINT, onSIGINT);
/* anonymous scope: mainloop */
{
int count = 0;
for (;;) {
system("clear");
printf("refresh number: %d.\n", count);
++count;
inspect();
sleep(1);
}
}
return 0;
}
여기에는 실제로 각 공유 파일을 사용하고 있음을 보여주기 위해 각 디스플레이 반복마다 각 바이트가 증가하는 버전이 있습니다. 성공적 내가 정력에 바이트 중 하나를 변경할 순간까지 각 바이트를 증가 유지하는 것이
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
// | bag of global state.
struct {
uint8_t *state;
char *filename;
int length;
} global = {
(uint8_t *)0,
"state.bin",
16
};
// | clean up when ctrl-c is pressed.
static void onSIGINT(int unused)
{
puts("caught SIGINT; cleaning up.");
munmap(global.state, global.length);
unlink(global.filename);
exit(0);
}
// | prints length bytes starting at address given.
static void inspect()
{
int i;
for (i = 0; i < global.length; ++i) {
printf("state[%d] = %d.\n", i, global.state[i]);
++global.state[i];
}
}
int main(int argc, char **argv)
{
/* anonymous scope: initialize shared memory */
{
// | mmap arguments
void *addr = (void *)0;
int prot = PROT_READ | PROT_WRITE;
int flags = MAP_SHARED;
int offset = 0;
int fd = open(global.filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
// | initialize memory to 16 zerod out bytes.
uint8_t dummy[16];
memset(&dummy, 0, global.length);
write(fd, dummy, global.length);
global.state = (uint8_t *)mmap (
addr,
global.length,
prot,
flags,
fd,
offset
);
if (global.state == MAP_FAILED) {
close(fd);
perror("could not create map.\n");
unlink(global.filename);
}
}
signal(SIGINT, onSIGINT);
/* anonymous scope: mainloop */
{
int count = 0;
for (;;) {
system("clear");
printf("refresh number: %d.\n", count);
++count;
inspect();
sleep(1);
}
}
return 0;
}
참고. 파일을 덮어 쓰면 파일 수정이 중지되지만 관계없이 계속 계산됩니다.
왜 이런 식으로 행동합니까? 예상대로 작동하게하려면 어떻게해야합니까?
이 작동 안 첫 번째 프로그램이 되었습니까? 나는 그것을 실행하고 Vim으로 파일을 수정했다. 업데이트 된 값을 보여주었습니다. 예 : * :'state [1] = 50.'을 'NUL'중 하나를 '2'로 바꿀 때. – giusti
O.o 그것은 나를 위해 작동하지 않는 것 ... 나를 다시 시도하자. 나는 두 대의 컴퓨터에서 시도해 보았고 0 : – Dmitry
예, 둘 다 내 컴퓨터에서 작동하지 않습니다. 데비안의 다른 우분투 중 하나를 다시 확인했습니다. – Dmitry