首页 > 解决方案 > write() 以错误的顺序打印

问题描述

我正在尝试输出由多个进程创建的有序行集。

我发现printf()并不fprintf()适合这样的任务。现在我正在使用这组命令:

sprintf(buff,"%d: some string", (*counter)++); //build string (write can't do that)
write(file, buff, strlen(buff));
memset(buff, 0, strlen(buff)); //clear buffer before next writing

文件打开和启动过程如下图所示:

int file;
int main(){
    pid_t busPID, riderPID;
    file = open("outputFile.txt", O_WRONLY | O_CREAT | O_APPEND | O_TRUNC, 0666);
    if((busPID = fork()) == 0){
        bus();
    else{
        if((riderPID = fork()) == 0){
            for(int i = 0; i < 10; i++){
                rider();
            }
        }else{
            pid_t waitPID;
            while ((waitPid = wait(&status)) > 0); //wait for all riders to finish
        }
    }
    waitpid(busPID, NULL, 0);
    return 0;
}

以下是打印输出的函数:

void bus() {
    char buff[50];
    //writing
    do {
        //writing
        if(*onStop > 0) {
            //writing
            sem_post(semRider);
            sem_wait(semBus);
            //writing
            *onStop = 0; //internal value, irrelevant for answer
        }
        //writing
        usleep(rand()%busSleep);
        //writing
        sem_post(semRider);
        sem_wait(semBus);
        departuredAkt += temp; //internal value, irrelevant for answer
    } while(departuredAkt < departuredTotal);
    //writing
    exit(EXIT_SUCCESS); //exit this process
}

void rider() {
    char buff[50];
    //writing
    int pos = ++(*onStop);
    //writing
    sem_wait(semRider);
    //writing
    sem_post(semBus);
    sem_wait(semRider);
    //writing
    sem_post(semBus);
    exit(EXIT_SUCCESS);
}

只有 1 个进程使用bus()函数,N 个进程使用rider()函数(由参数指定)。所需的输出是:

1: bus string
2: bus string
3: bus string
4: rider 1 string
5: rider 1 string
.
.
.
25: rider N string
26: bus string

我当前的输出如下所示:

1: bus string
2: bus string
3: bus string
4: rider 1 string
6: bus string //here is the problem
5: rider 1 string

问题是,我怎样才能以正确的顺序实现打印线?

标签: c

解决方案


首先,附注:永远不要使用sprintf,这个功能是完全不安全的。使用snprintf. 例子:

snprintf (buff, sizeof (buff), "%d: some string", (*counter)++);

第二:您错过了我们需要了解您的问题的信息。我的意思是以下信息:

  • 你究竟是如何打开文件的?
  • 你是如何开始你的流程的?
  • 这个进程真的是进程还是线程?
  • 您是否在一个进程中打开文件并以某种方式与其他进程共享此打开的文件,或者您是否分别在每个进程中打开文件?

这些细节对于理解您的问题至关重要。

下次您要写一些问题时,请提供完整示例。IE。我们可以编译和运行的最小工作示例。它应该包括所有相关的细节,即启动进程、打开文件等。当然,你应该去掉所有不必要的细节。

好的,POSIX 中有两个不同的概念:“文件描述符”和“文件描述符”。网络搜索他们。在 UNIX shell 中键入“man 2 open”并仔细阅读,本手册页讨论了区别。

有关如何启动进程以及如何打开文件的确切详细信息会导致(或不导致)进程之间共享文件描述,从而影响“写入”行为。

我写了关于文件描述符和描述的大文本。我把它放在这里:https ://zerobin.net/?eb2d99ee02f36b92#hQY7vTMCD9ekThAod+bmjlJgnlBxyDSXCYcgmjVSu2w= ,因为它与这个问题没有太大关系,但仍然对教育有用。

好吧,怎么办?

好吧,如果您出于某种原因无法共享一个文件说明,那么只需使用 O_APPEND 打开文件。:) 您不需要每次写入文件时都打开该文件。只需在每个进程中使用 O_APPEND 打开一次,一切都会好的。


推荐阅读