C Linux 中的信号量无法正常工作以进行文件操作



我编写了非常简单的程序,使用信号量:我创建信号量,多次分叉进程;在每个子进程中,我生成一种唯一的字符串,打开文件,而不是在无限循环中等待信号量,逐个字符写入输出文件"唯一字符串"字符并为另一个进程释放信号量。

但。。。它不知何故无法正常工作。我想知道为什么以及如何修复它。

这是我的代码:

/* test.c */
// gcc test.c -o test -lpthread
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h> 
#include <semaphore.h>
#include <time.h>
#include <fcntl.h>

#define SEMAPHORE_NAME      "write_sync_sem"

void child_process_routine(sem_t **semaphore);

int main(int argc, char const *argv[])
{
    /*  
        Create semaphore
    */
    sem_t *semaphore = sem_open(SEMAPHORE_NAME, O_CREAT, 0644, 1);
    if (semaphore == SEM_FAILED)
    {
        perror("Failed to create semaphore");
        exit(EXIT_FAILURE);
    }   
    int i = 0;
    for (i = 0; i < 5; ++i)
    {
        pid_t pid = fork();
        switch (pid)
        {
            case -1:
                perror("Failed to fork process.n");
                exit(EXIT_FAILURE);
            break;
            case 0:
                child_process_routine(&semaphore);
            break;
            default:
                printf("i = %dn", i);
            break;
        }
    }
    getchar();
    sem_close(semaphore);
    return 0;
}
void child_process_routine(sem_t **semaphore)
{
    time_t tm;
    srand((unsigned)time(&tm) + getpid());
    int unique_number = rand();
    char unique_str[50] = {0};
    sprintf(unique_str, "such string wow very unique %d-%dn", (int)tm, unique_number);
    int fd = open("output", O_RDWR | O_CREAT, 0666);
    if (fd == -1)
    {
        perror("Failed to open output file");
        exit(EXIT_FAILURE);
    }
    while (1)
    {
        if (sem_wait(*semaphore) == -1)
        {
            perror("Error waiting for semaphore");
            exit(EXIT_FAILURE);
        }

        char *pCh = unique_str;
        while (*pCh != '')
        {
            if (write(fd, pCh, sizeof(char)) == -1)
            {
                perror("Error writing to output file");
                exit(EXIT_FAILURE);
            }
            pCh++;
        }

        if (sem_post(*semaphore) == -1)
        {
            perror("Error releasing semaphore");
            exit(EXIT_FAILURE);
        }
    }
    close(fd);
}

预期产出:

such string wow very unique 1425893996-318951960
such string wow very unique 1425893996-318951960
such string wow very unique 1425893996-926144838
such string wow very unique 1425893996-926144838
such string wow very unique 1425893996-1232743880
...

但是得到:

such string wow very unique 1425893996-926144838
such string wow very unique 1425893996-926144838
such string wow very unique 1425893996-926144838
such string wow very unique 1425893996-926144838
such string wow very unique 14258939such string wow very unique 1425893996-1232743880
such string wow very unique 1425893996-1232743880
such string wow very unique 1425893996-1232743880
such string wow very unique 1425893996-123274388such string wow very unique 1425893996-624961104
such string wow very unique 1425893996-624961104
such string wow very unique 1425such string wow very unique 1425893996-18011055
such string wow very unique 1425893996-18011055
such string wow very unique 1425893996-18011055
such string wow very unique 1425893996-18011055
such string wow very unique 1425893996-18011055

写入是缓冲的。尝试在打开调用中使用O_SYNC或在写入 while 循环后调用 fsync(),以确保在释放信号量之前将数据刷新到磁盘。

the local file structure[fd] is probably not updated
across the children, as they each open'd the file separately. 
Suggest 
always opening file with 'FILE * fp = fopen( "output", "r" );  
then in the child, after getting the semaphore,
calling 'fseek( fp, 0, SEEK_END );'  
then going into the loop to write to the file  
after the loop ends, call 'fflush( fp );'
then releasing the semaphore
Although the parent process can eventually exit
(or abruptly exit via 'exit()')
The children never exit, 
so when the parent exits, the children become zombies.
Note: zombie processes are difficult to get rid of
short of rebooting the computer
Note: in main(), after closing the semaphore
a call to sem_unlink() needs to be performed
otherwise the semaphore continues to exist 

最新更新