Я создаю несколько дочерних процессов, и все они печатают в один и тот же файл STDOUT, даже если им приходится ждать мьютекса для печати и даже fflush (stdout), печать все равно перекрывает друг друга.
Я добавил мьютексы для окружения каждого printf, я даже добавил fflush после каждого оператора печати. Я пытался добавить только один fflush и пробовал это различными способами, помещая fflush в разные части кода.
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <errno.h>
#include <time.h>
#include <sys/wait.h>
#include "wrappers.c"
#include "shmSegment.h"
#include "message.h"
/*
argv[1] = id,
argv[2] = capacity
argv[3] = duration (ms)
*/
int main(int argc, char *argv[])
{
int myID = atoi(argv[0]);
int capacity = atoi(argv[1]);
int duration = atoi(argv[2]);
//#iterations=#partsMadeByMe=0;
int numIterations;
int numPartsMadeByMe;
numIterations = numPartsMadeByMe = 0;
//get shared memory
int shmid ;
key_t shmkey;
int shmflg;
shmData *p;
shmkey = ftok("shmSegment.h" , 1 ) ;
shmflg = IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
shmid = shmget( shmkey , SHMEM_SIZE , shmflg ) ;
p = (shmData *) Shmat( shmid , NULL , 0 );
//get message queue
msgBuf msgSnd;
int queID ;
int msgStatus ;
queID = Msgget( BASE_MAILBOX_NAME , 0600) ;
//get mutex
int semflg, semmode ;
semflg = O_CREAT;
semmode = S_IRUSR | S_IWUSR;
sem_t *mutex;
mutex = Sem_open2("/mutex", semflg);
Sem_wait(mutex);
printf("%d STARTED.\n", myID);
fflush(stdout);
Sem_post(mutex);
int job = 0;
Sem_wait(&(p->memMutex));
//while parts still remain
while(p->numPartsNeeded > 0)
{
//determine how many to make and update remain
if (p->numPartsNeeded >= capacity)
{
job = capacity;
} else
{
job = p->numPartsNeeded;
}
p->numPartsNeeded -= job;
p->numPartsBuilt += job;
Sem_post(&(p->memMutex));
//mutex
Sem_wait(mutex);
//print “%d: Going to make %d in %d milliSecs” , myID, data ...
printf("%d: Going to make %d in %d milliSecs\n", myID, job, duration);
fflush(stdout);
Sem_post(mutex);
//sleep(myDuration)
usleep(1000 * duration);
//create and send production message
msgSnd.msgType = TYPE_PRODUCTION;
msgSnd.body.lineID = myID;
msgSnd.body.numParts = job;
msgSnd.body.time = duration;
msgStatus = msgsnd( queID , &msgSnd , MSG_INFO_SIZE , 0 );
//increment #iterations
numIterations++;
//update total number of parts made by me
numPartsMadeByMe += job;
Sem_wait(&(p->memMutex));
}
Sem_post(&(p->memMutex));
//create and send completion message
msgSnd.msgType = TYPE_TERMINATION;
msgSnd.body.lineID = myID;
msgSnd.body.numParts = numPartsMadeByMe;
msgSnd.body.time = numIterations;
msgStatus = msgsnd( queID , &msgSnd , MSG_INFO_SIZE , 0 );
if ( msgStatus < 0 )
{
printf("Failed to send on queuID %d. Error code=%d\n"
, queID , errno ) ;
perror("Reason");
exit(-2) ;
}
Sem_wait(mutex);
printf(">>>> %4d: Terminating after making total of %5d in %4d iterations\n",
myID, numPartsMadeByMe, numIterations);
fflush(stdout);
Sem_post(mutex);
shmdt( p ) ;
shmctl( shmid , IPC_RMID , NULL );
sem_close(mutex); sem_unlink("/mutex");
exit(1);
}
Если у меня одновременно запущены два процесса, я ожидаю вывод, подобный
1 STARTED
2 STARTED
1: Going to make 15 parts in 734 milliSecs
2: Going to make 10 parts in 528 milliSecs
2: Going to make 10 parts in 528 milliSecs
1: Going to make 15 parts in 734 milliSecs
[...]
>>>> 1: Terminating after making total of 90 parts in 6 iterations
>>>> 2: Terminating after making total of 60 parts in 6 iterations
порядок вывода не имеет значения, но когда я запускаю его с fflush после каждой печати, выходной файл выглядит примерно так:
2 STARTED.
2: Going to make 43 in 763 milliSecs12: Going to make 43 in 763 milliSec1:2: Going to make 43 in 763 milliSe1: 2: Going$>>>> 2: Terminating after making total of 135 in 4 iterations
otal of 15 in 5 iterations
только с одним fflush дает тоже не работает. Типичные выходы только с одним fflush:
1 STARTED.
1: Going to make 18 in 547 milliSecs
2: Going to make 2 in 1176 milliSecs
2: Going to make 2 in 1176 milliSecs
2: Going to make 2 in 1176 milliSecs
>>>> 2: Terminating after making total of 8 in 4 iterations
ecs
1: Going to make 18 in 547 milliSecs
1: Going to make 16 in 547 milliSecs
>>>> 1: Terminating after making total of 142 in 8 iterations
2 STARTED.
2: Going to make 48 in 945 milliSecs
2: Going to make 22 in 945 milliSecs
>>>> 2: Terminating after making total of 70 in 2 iterations