我有以下問題。錯誤地寫入同步進程的文件輸出順序?
我正在與信號燈同步的兩個過程和思路是這樣的:
- 過程1寫東西txt文件
- 過程2寫東西txt文件
- 過程1寫東西的測試文件
我已經包含演示該問題此示例代碼:
// semaphore names
#define NAME1 "/s1"
#define NAME2 "/s2"
int main()
{
/* semaphores for process synchronization */
sem_t *sm1;
sm1 = sem_open(NAME1, O_CREAT, 0666, 0);
sem_t *sm2;
sm2 = sem_open(NAME2, O_CREAT, 0666, 0);
/* processes*/
int proc1;
int proc2;
/* file lock struct */
struct flock fl = {F_WRLCK, SEEK_SET, 0, 0, 0 };
/* create a text file */
FILE *fp;
int fd;
fp = fopen("output.txt", "w"); // create and close the file
fclose(fp);
if((fd = open("output.txt", O_RDWR)) == -1) { // open the file again to get file descriptor
perror("open");
exit(1);
}
fp = fdopen(fd, "w");
/* first process */
if ((proc1 = fork()) < 0) {
perror("fork");
exit(2);
}
else if(proc1 == 0) {
fl.l_type = F_WRLCK; // set the lock type and pid of the forked process
fl.l_pid = getpid();
if (fcntl(fd, F_SETLKW, &fl) == -1) { // lock the file before writing to it
perror("fcntl");
exit(1);
}
fprintf(fp, "proc1 - action1\n"); // write to the file
fl.l_type = F_UNLCK;
if (fcntl(fd, F_SETLK, &fl) == -1) { // unlock the file so other processes can write to it
perror("fcntl");
exit(1);
}
fprintf(stdout, "proc1 - action1\n");
sem_post(sm1); // let the second process run
sem_wait(sm2); // wait till the second process is done
// write one more thing the same way to the text file after the second process is done
fl.l_type = F_WRLCK;
fl.l_pid = getpid();
if (fcntl(fd, F_SETLKW, &fl) == -1) {
perror("fcntl");
exit(1);
}
fprintf(fp, "proc1 - action2\n");
fl.l_type = F_UNLCK;
if (fcntl(fd, F_SETLK, &fl) == -1) {
perror("fcntl");
exit(1);
}
fprintf(stdout, "proc1 - action2\n");
exit(0);
}
/* second process */
if ((proc2 = fork()) < 0) {
perror("fork");
exit(2);
}
else if(proc2 == 0) {
sem_wait(sm1); // waits for proc1 to perform it's first action
// write something to the text file and let proc1 write it's second action
fl.l_type = F_WRLCK;
fl.l_pid = getpid();
if (fcntl(fd, F_SETLKW, &fl) == -1) {
perror("fcntl");
exit(1);
}
fprintf(fp, "proc2 - action1\n");
fl.l_type = F_UNLCK;
if (fcntl(fd, F_SETLK, &fl) == -1) {
perror("fcntl");
exit(1);
}
fprintf(stdout, "proc2 - action1\n");
sem_post(sm2);
exit(0);
}
// wait for both processes to finish
waitpid(proc1, NULL, 0);
waitpid(proc2, NULL, 0);
sem_close(sm1);
sem_unlink(NAME1);
sem_close(sm2);
sem_unlink(NAME2);
return 0;
}
我已經包含在標準輸出線fprintf中,這樣就可以看到,在終端的輸出是正確的:
-proc1 - action1
-proc2 - action1
-proc1 - action2
就像他們正在同步。但是,output.txt文件中的輸出爲:
-proc2 - action1
-proc1 - action1
-proc1 - action2
爲什麼會發生這種情況?
此外,在進程寫入文件之前,我總是鎖定它,以便其他進程無法訪問它並再次解鎖。
我不確定我是否做得對,所以我會很感激我能得到的任何建議!
非常感謝!
另請參閱https://www.quora.com/In-C-what-does-buffering-IO-or-buffered-IO-mean – JimmyB
我編輯瞭如下代碼:fseek(fp,0,SEEK_END) ; fprintf(fp,「proc1 - action1 \ n」); fflush(fp);它似乎在工作。我做對了嗎?非常感謝您的信息!請問,文件鎖定怎麼辦?我是否正確地使用每個寫入操作來鎖定和解鎖文件?我正在考慮是否有更優雅的方式來做這件事,因爲當我可以說,10在每個進程中寫這樣的動作時,代碼很快就變得亂七八糟。 – Daeto