本文介绍了_pipe()与fopen()CRT调用中的死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Windows XP SP3中使用Visual Studio 6.0 SP6.

 i am using Visual studio 6.0 SP6 in windows XP SP3.

mine是控制台应用程序,并且是多线程的.当一个线程调用fopen(),同时另一个线程调用_pipe()时,我的程序将随机挂起.如果我使用msvcrt.dll 7.0.2600.5512,则不会观察到此挂起.

mine is console application and multithreaded. when one thread calls fopen() and at the same time if the other thread calls _pipe() then my programs hangs randomly. this hang is not observed if i use msvcrt.dll 7.0.2600.5512.

thread1->调用_pipe(filedes,4096,0);
线程2->用NULL设备调用fopen. fopen("NUL:","w");

thread1 -> calls _pipe(filedes,4096,0);
thread 2 -> calls fopen with NULL device. fopen("NUL:","w");

msvcrt.dll 7.0.2600.5512 ->      无死锁
msvcrtd.dll 6.0.9782.0 ->  死锁
libcmt.lib ->死锁
libcmtd.lib->死锁

msvcrt.dll 7.0.2600.5512  ->      No deadlock
msvcrtd.dll 6.0.9782.0  ->   Deadlock
libcmt.lib  ->  dead lock
libcmtd.lib -> Dead lock

下面是解释此问题的示例代码.

below is the sample code to explain the issue.

此问题在最新的CRT中是否已知并已解决?我在VS2008中尝试了相同的代码.没有死锁.

is this problem known and solved in latest CRT ? i tried the same code in VS2008. there is no deadlock.


#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>


char *WrapmyName = "PipeDeadLockTestAPP";


#ifdef WRAPPRINT

#define printf  Wrapprintf		
#define fprintf Wrapfprintf

void Wrapprintf(char *format, ...);
void Wrapfprintf(FILE *file, const char * format, ...);

#endif


unsigned __stdcall threadProc(void *threadStructval);
BOOL  bFlag = FALSE;

main(int argc,char* argv,char* env)
{
	FILE *fp = NULL;
    HANDLE*	hThread = NULL;
    int i = 0;

	fprintf(stdout,"Main Thread Running Infinitely using fprintf\n");
	printf("Main Thread Running Infinitely using printf\n");

    hThread = (HANDLE)_beginthreadex(NULL,0,threadProc,NULL,0,NULL);

	while(!bFlag)
	{	
		fp = fopen("MyFile.txt", "a");
		if( fp)
		{
			fprintf(fp, "%s %d %s %d %d %d %d %s\n",  
					fp->_ptr, fp->_cnt, fp->_base, fp->_flag, fp->_file, fp->_charbuf, fp->_bufsiz, fp->_tmpfname);
			fclose(fp);
		}
	}
}

unsigned __stdcall threadProc(void *threadStructval)
{
	int hpipe[2];
	int i, ret;

	FILE *tempFp1 = NULL;

	tempFp1 = fopen("MyTempFile.txt", "w");

	printf("threadProc started using printf\n");
	fprintf(stdout,"threadProc started using fprintf\n");

	for(i=0; i<2000; i++)
	{
		ret = _pipe( hpipe, 10, O_BINARY );
		if( ret == 0 )
		{
			fprintf(tempFp1, "read handle = %u, write handle = %u\n", hpipe[0], hpipe[1]);
            close(hpipe[0]);
			close(hpipe[1]);
		}
	}

	if(tempFp1)
	{
		fclose(tempFp1);
	}

	printf("threadProc started End  using printf\n");
	fprintf(stdout,"threadProc End using fprintf\n");

	bFlag = TRUE;
}

void Wrapprintf(char *format, ...)
{
  va_list   ap;
  char      *fmt;
  FILE      *fp;
  /*  int       len;*/
  char      temp[512];
  char      ttyFile[32];
  
  fprintf(stdout,"%s : %d. Enter Wrapprintf(myName:%s)\n",__FILE__,__LINE__,WrapmyName);

  memset(ttyFile,0, sizeof(ttyFile));
  sprintf(ttyFile,"/tmp/%s.tty",WrapmyName);

  if ((fp = fopen(ttyFile, "r")) == (FILE*)NULL) 
  {
    if ((fp = fopen("NUL:","w")) == (FILE*)NULL) 
		return;
    
      fprintf(stdout,"opened (\\/dev\\/null)\n");
  }
  else 
  {   
    if (fscanf(fp, "%s", temp) != 1) 
	{
      if ((fp = fopen("NUL:","w")) == (FILE*)NULL)  return;
      
	fprintf(stdout,"opened (\/dev\/null)\n");
    }
    else 
	{
      fclose(fp);
      
      /*-----------------------------------------------*
       * if ((fp = fopen(temp, "w")) == (FILE*)NULL) {
       *-----------------------------------------------*/
      if ((fp = fopen(temp, "a")) == (FILE*)NULL) 
	  {
		  if ((fp = fopen("NUL:","w")) == (FILE*)NULL) 
			  return ;
		  fprintf(stdout,"opened (\/dev\/null)\n");
      } 
	  
	  fprintf(stdout,"opened (%s)\n",temp);
    }
  }
  
  va_start(ap, format);
  fmt = format;
  
  /***************************
   * vfprint(stderr, fmt, ap);
   **************************/
  vfprintf(fp, fmt, ap);  
  
  va_end(ap);
  
  fclose(fp);
  
}


void Wrapfprintf(FILE *file, const char * format, ...)
{
  va_list   ap;
  char      *fmt;
  FILE      *fp;
  /*  FILE      *dummy;*/
  /*  int       len;*/
  char      temp[512];
  char      ttyFile[32];


 sprintf(ttyFile,"/tmp/%s.tty",WrapmyName);

  if ((fp = fopen(ttyFile, "r")) == (FILE*)NULL) {
    if ((fp = fopen("NUL:","w")) == (FILE*)NULL)  return;
  }
  else {
    
    if (fscanf(fp, "%s", temp) != 1) {
      if ((fp = fopen("NUL:","w")) == (FILE*)NULL)  return;
    }
    else {
      fclose(fp);

      /*--------------------------------------------*
       * if ((fp = fopen(temp, "w")) == (FILE*)NULL)
       *--------------------------------------------*/
      if ((fp = fopen(temp, "a")) == (FILE*)NULL)
	if ((fp = fopen("NUL:","w")) == (FILE*)NULL)  return ;
    }
  }
  
  va_start(ap, file);

  fmt = va_arg(ap, char *);
  vfprintf(fp, fmt, ap);  
  
  va_end(ap);
  
  fclose(fp);
}



推荐答案

您可以使用"Mutex"在执行任何操作bt线程之前用于锁定目的..

You can use "Mutex" for locking purpose before doing any action bt thread.. 


这篇关于_pipe()与fopen()CRT调用中的死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 13:16