多进程/多线程同时向一个文件中写入日志如何避免冲突?
寫入文件時(shí)都會(huì)調(diào)用函數(shù) write,由于所有的系統(tǒng)調(diào)用都是原子的,所以該函數(shù)可以保證進(jìn)程或者線程寫入數(shù)據(jù)的過(guò)程中不會(huì)被其他進(jìn)程或者線程打擾,即:數(shù)據(jù)中間插入別的進(jìn)程的數(shù)據(jù)。
另外一個(gè)問題,由于 write 之前需要指定寫入位置,即:lseek 函數(shù),同樣,該函數(shù)也是原子的。
整體來(lái)說(shuō),在一個(gè)寫入數(shù)據(jù)的操作如下:
lseek(fd, 0, SEEK_END); // seek to the end of the filewrite(fd, "log message", len); // perform the writebut,這兩個(gè)函數(shù)需要依次完成,中間不能被別的進(jìn)程或者線程插入寫入它們的數(shù)據(jù),也就是說(shuō)為了保證多進(jìn)程或者多線程同時(shí)向一個(gè)文件中寫入數(shù)據(jù)時(shí)能夠避免沖突,需要上述兩個(gè)函數(shù)的執(zhí)行是事務(wù)性的。
為了解決這個(gè)問題,可以用標(biāo)志位 O_APPEND,其含義是在每次打開文件時(shí),都將標(biāo)志位移動(dòng)到文件的末端,這個(gè)過(guò)程時(shí)原子的。
#include <stdio.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h>int main() {char *filename = "my_data.txt";int fd = open(filename, O_WRONLY | O_CREAT);pid_t pid = fork();if (0 == pid){printf("this is child: %ld\n", (long)getpid());char buf[20];memset(buf, 'D', sizeof(buf));int fd = open(filename, O_WRONLY | O_CREAT | O_APPEND);write(fd, buf, sizeof(buf));close(fd);}else{printf("this is father: %ld\n", (long)getpid());char buf[30] = {2};memset(buf, 'A', sizeof(buf));buf[29] = '_';int fd = open(filename, O_WRONLY | O_CREAT | O_APPEND);write(fd, buf, sizeof(buf));close(fd);int status;wait(&status);}return 0; }結(jié)果:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAA_DDDDDDDDDDDDDDDDDDDD?
(SAW:Game Over!)
?
總結(jié)
以上是生活随笔為你收集整理的多进程/多线程同时向一个文件中写入日志如何避免冲突?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络安全 / crt、pem、pfx、
- 下一篇: 用 openssl 生成 SSL 使用的