问题描述
我需要编写一个程序来创建多线程进程,该程序正在创建另一个多线程进程,我遇到的问题是在两个进程的运行中有一些时间点,在打印到终端时彼此重叠。
>例如:
//father process
printf("I'm father process\n");
//child process
fprintf(stderr,"I'm child process\n");
结果:
I'I'mm fachtheril proprcesscoess
无论如何我可以确保这不会发生吗?
如果有帮助,父进程和子进程通过匿名管道连接。
添加编辑:
我在父进程中的主线程创建容器(线程),每个线程都有自己的 id 并宣布该容器开始工作。 那么线程本身需要使用管道并将他的id发送到子进程。当子进程通过管道获取 id 时,他宣布 id 到达。但在此之前,子进程会初始化另一个调用起重机的线程,这些线程具有不同的目的,它们也声明它们何时被创建。
*每个线程都有自己的信号量。 *在每次宣布线程进入休眠状态后 5-3000 毫秒。
所以问题只发生在父进程的主线程开始创建容器和子进程中的主线程创建起重机的开始时,打印重叠或开始一个句子停止启动另一个并返回到第一个。尽管所有的打印在一行中都有一个 /n 和命令。
父进程:
主线程:
/* 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,"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,TRUE,/* inherit handles */
0,&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,1,NULL);
if (vesselsSem[i] == NULL)
{
fprintf(stderr,"Main::Unexpected Error in Vessles Semaphore %d Creation\n",i);
return FALSE;
}
vesselsArr[i] = CreateThread(NULL,Vessel,&vesselsID[i],&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,INFINITE);
容器螺纹:
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",id);
Sleep(random());//Simulate a process
//send the id vessel to child port through pipe.
if (!WriteFile(InputWriteHandle,&id,"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");
}
}
子进程: 主线程:
for (int i = 0; i < numOfCrane; i++)
{
adtArr[i].craneID = i + 1;
cranesem[i] = CreateSemaphore(NULL,NULL);
if (cranesem[i] == NULL)
{
fprintf(stderr,"Main::Unexpected Error in Vessles Semaphore %d Creation @child\n",i);
return FALSE;
}
craneArr[i] = CreateThread(NULL,Crane,&adtArr[i].craneID,&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",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,&read,NULL))
{
vesselsID[(*buffer) - 1] = (*buffer);
vesselsSem[(*buffer) - 1] = CreateSemaphore(NULL,NULL);
if (vesselsSem[(*buffer) - 1] == NULL)
{
fprintf(stderr,(*buffer));
return FALSE;
}
vesselsArr[(*buffer) - 1] = CreateThread(NULL,&vesselsID[(*buffer) - 1],&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",*buffer);
Sleep(random());
}
}
我希望我能很好地解释自己。
解决方法
最简单的解决方案是添加换行符“\n”。
//father process
printf("I'm father process\n");
//child process
fprintf(stderr,"I'm child process\n");
这会阻止你的输出,但它不会阻止哪个先出现,父母的输出或孩子的输出。如果您希望该行为同步,则需要更复杂的同步(例如共享内存和互斥锁)。