I need to write a program that create process multithreaded which is creating another process multithreaded and the problem that I having is there are some point time in the running of the two processes there are overlapping each other in printing to terminal.
for example :
//father process
printf("I'm father process\n");
//child process
fprintf(stderr,"I'm child process\n");
the outcome :
I'I'mm fachtheril proprcesscoess
is there anyway I can make sure that will not happen ?
the father and the child processes are connected with anonymous pipe if it's help.
add editing :
my main thread in the father process creating the vessels (threads) that each one have it's own id and announce this vessel is starting to work. then the thread itself need to use the pipe and sent his id to the child process. when the child process gets the id though the pipe he announce that the id arrived. but before that the child process initialize other thread that called crane with different purpose that also announce when they are created.
*each thread has it's own semaphore. *after each announce the thread enter to sleep between 5-3000 milliseconds.
so the problem it's happing only in the beginning when the main thread of the father process start creating the vessel and the main thread in the child process creating the cranes, there printing is overlapping or start one sentence stop start another one and return to the first one. though all the printing have a /n and command in one line.
I will try to add minimal reproducible example of my code:
father process:
main thread:
/* create Input the pipe */
if (!CreatePipe(&InputReadHandle, &InputWriteHandle, &sa, 0)) {
fprintf(stderr, "Main::Create Pipe Failed @ father\n");
return 1;
}
/* create Output the pipe */
if (!CreatePipe(&OutputReadHandle, &OutputWriteHandle, &sa, 0)) {
fprintf(stderr, "Main::Create Pipe Failed @ father\n");
return 1;
}
/* establish the START_INFO structure for the child process */
GetStartupInfo(&si);
si.hStdError = GetStdHandle(STD_OUTPUT_HANDLE);
/* redirect the standard input/output to the read end of the pipe */
si.hStdOutput = OutputWriteHandle;
si.hStdInput = InputReadHandle;
si.dwFlags = STARTF_USESTDHANDLES;
/* we do not want the child to inherit the write end of the pipe */
SetHandleInformation(InputWriteHandle, HANDLE_FLAG_INHERIT, 0);
wcscpy(ProcessName, L"..\\..\\child\\Debug\\child.exe");
/* create the child process */
if (!CreateProcess(NULL,
ProcessName,
NULL,
NULL,
TRUE, /* inherit handles */
0,
NULL,
NULL,
&si,
&pi))
{
fprintf(stderr, "Main::Process Creation Failed @ father\n");
return -1;
}
/* father now wants to write to the pipe */
if (!WriteFile(InputWriteHandle, &numOfVessels, BUFFER_SIZE, &written, NULL))
fprintf(stderr, "Main::Error writing to pipe\n");
. . .
// Create all vessel Threads. Report if Error occurred!
for (int i = 0; i < numOfVessels; i++)
{
vesselsID[i] = i+1;
vesselsSem[i] = CreateSemaphore(NULL, 0, 1, NULL);
if (vesselsSem[i] == NULL)
{
fprintf(stderr, "Main::Unexpected Error in Vessles Semaphore %d Creation\n", i);
return FALSE;
}
vesselsArr[i] = CreateThread(NULL, 0, Vessel, &vesselsID[i], 0, &ThreadId);
if (vesselsArr[i] == NULL) {
fprintf(stderr,"Main::Unexpected Error in Thread %d Creation\n", i);
exit(1);
}
}
//wait to all thread(vessel) to finish.
WaitForMultipleObjects(numOfVessels, vesselsArr, TRUE, INFINITE);
vessel thread :
DWORD WINAPI Vessel(PVOID Param)
{
int id = *(int*)Param;
printf("%s Vessel %d - starts sailing @ father\n", getTime(),id);
Sleep(random());//Simulate a process Sailing
//sent to child .
// make sure only one vessel at the time enter to the canal.
WaitForSingleObject(mutex, INFINITE);
printf( "%s Vessel %d - senting to child @father\n", getTime(), id);
Sleep(random());//Simulate a process
//send the id vessel to child port through pipe.
if (!WriteFile(InputWriteHandle, &id, BUFFER_SIZE, &written, NULL))
fprintf(stderr, "Error writing to pipe @ father\n");
// the vessel has been sent and can be release .
if (!ReleaseMutex(mutex))
{
fprintf(stderr, " Unexpected error mutex.V()\n");
}
}
child process: main thread:
for (int i = 0; i < numOfCrane; i++)
{
adtArr[i].craneID = i + 1;
craneSem[i] = CreateSemaphore(NULL, 0, 1, NULL);
if (craneSem[i] == NULL)
{
fprintf(stderr, "Main::Unexpected Error in Vessles Semaphore %d Creation @child\n", i);
return FALSE;
}
craneArr[i] = CreateThread(NULL, 0, Crane, &adtArr[i].craneID, 0, &ThreadId);
if (craneArr[i] == NULL) {
fprintf(stderr, "main::Unexpected Error in Thread %d Creation @child \n", i);
exit(1);
}
adtArr[i].cargo = 0;
adtArr[i].vesselID = 0;
fprintf(stderr, "%s Crane %d created @child \n", getTime(), adtArr[i].craneID);
}
. . .
//read the vessel from pipe
for (int i = 0; i < numOfVessels; i++)
{
//if readfile is empty then it's wait.
if (ReadFile(ReadHandle, buffer, BUFFER_SIZE, &read, NULL))
{
vesselsID[(*buffer) - 1] = (*buffer);
vesselsSem[(*buffer) - 1] = CreateSemaphore(NULL, 0, 1, NULL);
if (vesselsSem[(*buffer) - 1] == NULL)
{
fprintf(stderr, "Main::Unexpected Error in Vessles Semaphore %d Creation\n", (*buffer));
return FALSE;
}
vesselsArr[(*buffer) - 1] = CreateThread(NULL, 0, Vessel, &vesselsID[(*buffer) - 1], 0, &ThreadId);
if (vesselsArr[(*buffer) - 1] == NULL) {
fprintf(stderr, "main::Unexpected Error in Thread %d Creation \n", (*buffer));
exit(1);
}
barrier[i] = (*buffer); // need to write abinormal behavier
fprintf(stderr, "%s Vessel %d - arrirved @ child \n", getTime(), *buffer);
Sleep(random());
}
}
I hope I did well to explain myself.