write()以错误的顺序打印

时间:2018-04-26 21:18:39

标签: c

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

我发现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

问题是,如何以正确的顺序实现打印行?

1 个答案:

答案 0 :(得分:1)

首先,旁注:永远不要使用sprintf,这个功能完全不安全。使用snprintf。例如:

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

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

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

此详细信息对于理解您的问题至关重要。

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

Okey,POSIX中有两种不同的概念:“文件描述符”和“文件说明”。为他们进行网络搜索。在UNIX shell中键入“man 2 open”并仔细阅读,本手册页介绍了区别。

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

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

哦,该怎么办?

好吧,如果您因任何原因无法共享一个文件描述,那么只需使用O_APPEND打开文件即可。 :)每次写入文件时都不需要打开文件。只需在每个过程中用O_APPEND打开一次,一切都会好的。