I want to write log files using mmap
in multi-process server, the processes can write to the initial log file, but if one process modify the shared address to a new file, other processes can not perceive this. The codes are like this:
firstly: open a file and map it to shared memory;
secondly: child process writes something to the file
thirdly: child process open a new log and modify the shared memory to the new file
fourthly: parent process writes something to the log file. I want the parent process write to the new log, but it writes to the old file. This means the parent process does not know the modification of child process.
my question is : How can the parent(or other children) process perceive the modification of the shared memory, and write to the new file?
typedef struct shared_mgs_s {
log_atomic_t lock;
int offset;
} shared_msg_t;
char *write_addr;
shared_msg_t *sm;
log_atomic_t *log_mutex_ptr;
#define FILE_SIZE 1 * 1024 * 1024
int map_log_file(char *file_name)
{
// create a log file and map it to shared memory
int fd = -1;
if ((fd = open(file_name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0)
{
printf("create %s failed %d\n",file_name, errno);
return -1;
}
if (ftruncate(fd, FILE_SIZE) < 0)
{
printf("ftruncate %d failed", errno);
return -1;
}
write_addr = (char*)mmap(NULL, FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
sm->offset = 0;
return 0;
}
void write_log(char *msg)
{
memcpy(write_addr + sm->offset, msg, strlen(msg));
sm->offset += strlen(msg);
}
int create_shared_info()
{
sm = mmap(NULL, 64, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (!sm)
return -1;
sm->offset = 0;
sm->lock = 0;
log_mutex_ptr = &(sm->lock);
}
int main()
{
if(create_shared_info() < 0)
{
printf("create shared info failed\n");
return -1;
}
if(map_log_file("./old.log") != 0)
{
printf("map old log failed\n");
return -1;
}
if(0 == fork())
{
log_spinlock(log_mutex_ptr, 1, 2048);
munmap(write_addr, FILE_SIZE);
if(map_log_file("./new.log") != 0)
{
printf("create new log failed\n");
return -1;
}
write_log("from child\n");
log_unlock(log_mutex_ptr);
exit(0);
} else {
usleep(10); // make sure child process get lock firstly, just test use the new file
log_spinlock(log_mutex_ptr, 1, 2048);
write_log("from parent\n");
log_unlock(log_mutex_ptr);
}
return 0;
}
in the way, the parent writes to old.log
, this is not what I want, I want it write to the new one.