多线程下 每个线程打印各自的进度 谢谢

laoshizhuce 2015-10-18 07:43:22
各位高手
如何实现每个线程打印各自的进度,
类似下面的输出
也就是说
在控制台下
每个线程输出一行
这行用来更新自己的进度

thanks

51% [===========================> ] 48,816,320 69.4MB/s
40% [====================> ] 48,816,320 50.4MB/s
60% [=================================> ] 48,816,320 69.4MB/s
...全文
465 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
laoshizhuce 2015-10-23
  • 打赏
  • 举报
回复
自己顶下顶下
赵4老师 2015-10-23
  • 打赏
  • 举报
回复
main的最后加一句getchar();再试试。
laoshizhuce 2015-10-20
  • 打赏
  • 举报
回复
#include <cstdio> #include <unistd.h> #include <thread> #include <mutex> std::mutex mtx; void func1 () { int i=0; while(1) { i++; { std::lock_guard<std::mutex> lck (mtx); printf("func1 %3d \r",i); fflush(stdout); } sleep(1); } } void func2 () { int i=0; printf("\n"); while(1) { i=i+3; { std::lock_guard<std::mutex> lck (mtx); printf("func2 %3d \r",i); fflush(stdout); } sleep(1); } } int main (void) { std::thread([]{printf("%s %d\n",__func__,__LINE__);}).join(); std::thread t1=std::thread(func1); std::thread t2=std::thread(func2); t1.join(); t2.join(); } 我自己写了一个程序 发现只有func2有更新,func1压根没有 有人知道是什么原因吗
laoshizhuce 2015-10-20
  • 打赏
  • 举报
回复
楼上的还有别的方式吗
赵4老师 2015-10-19
  • 打赏
  • 举报
回复
再供参考:

/******************************************************************************\
*       This is a part of the Microsoft Source Code Samples.
*       Copyright (C) 1993 Microsoft Corporation.
*       All rights reserved.
*       This source code is only intended as a supplement to
*       Microsoft Development Tools and/or WinHelp documentation.
*       See these sources for detailed information regarding the
*       Microsoft samples programs.
\******************************************************************************/

/*  Bounce - Creates a new thread each time the letter 'a'is typed.
 *  Each thread bounces a happy face of a different color around the screen.
 *  All threads are terminated when the letter 'Q' is entered.
 *
 *  This program requires the multithread library. For example, compile
 *  with the following command line:
 *      CL /MT BOUNCE.C
 */

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>

#define MAX_THREADS  32

/* getrandom returns a random number between min and max, which must be in
 * integer range.
 */
#define getrandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))

void main( void );                     /* Thread 1: main */
void KbdFunc( void  );                 /* Keyboard input, thread dispatch */
void BounceProc( char * MyID );        /* Threads 2 to n: display */
void ClearScreen( void );              /* Screen clear */
void ShutDown( void );                 /* Program shutdown */
void WriteTitle( int ThreadNum );      /* Display title bar information */

HANDLE  hConsoleOut;                   /* Handle to the console */
HANDLE  hRunMutex;                     /* "Keep Running" mutex */
HANDLE  hScreenMutex;                  /* "Screen update" mutex  */
int     ThreadNr;                      /* Number of threads started */
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;   /* Console information */


void main()                            /* Thread One */
{
    /* Get display screen information & clear the screen.*/
    hConsoleOut = GetStdHandle( STD_OUTPUT_HANDLE );
    GetConsoleScreenBufferInfo( hConsoleOut, &csbiInfo );
    ClearScreen();
    WriteTitle( 0 );
    /* Create the mutexes and reset thread count. */
    hScreenMutex = CreateMutex( NULL, FALSE, NULL );   /* Cleared */
    hRunMutex = CreateMutex( NULL, TRUE, NULL );       /* Set */
    ThreadNr = 0;

    /* Start waiting for keyboard input to dispatch threads or exit. */
    KbdFunc();

    /* All threads done. Clean up handles. */
    CloseHandle( hScreenMutex );
    CloseHandle( hRunMutex );
    CloseHandle( hConsoleOut );
}

void ShutDown( void )                  /* Shut down threads */
{
    while ( ThreadNr > 0 )
    {
            /* Tell thread to die and record its death. */
            ReleaseMutex( hRunMutex );
            ThreadNr--; 
    }
    /* Clean up display when done */
    WaitForSingleObject( hScreenMutex, INFINITE );
    ClearScreen();
}

void KbdFunc( void )                   /* Dispatch and count threads. */
{
    int         KeyInfo;

    do
    {
        KeyInfo = _getch();
        if( tolower( KeyInfo ) == 'a' && ThreadNr < MAX_THREADS )
        {
            ThreadNr++;
            _beginthread( BounceProc, 0, &ThreadNr );
            WriteTitle( ThreadNr );
        }
    } while( tolower( KeyInfo ) != 'q' );

    ShutDown();
}

void BounceProc( char *MyID )
{
    char      MyCell, OldCell;
    WORD      MyAttrib, OldAttrib;
    char      BlankCell = 0x20;
    COORD     Coords, Delta;
    COORD     Old = {0,0};
    DWORD     Dummy;

/* Generate update increments and initial display coordinates. */
    srand( (unsigned) *MyID * 3 );
    Coords.X = getrandom( 0, csbiInfo.dwSize.X - 1 );
    Coords.Y = getrandom( 0, csbiInfo.dwSize.Y - 1 );
    Delta.X = getrandom( -3, 3 );
    Delta.Y = getrandom( -3, 3 );

    /* Set up "happy face" & generate color attribute from thread number.*/
    if( *MyID > 16)
        MyCell = 0x01;                 /* outline face */
    else
        MyCell = 0x02;                 /* solid face */
    MyAttrib =  *MyID & 0x0F;          /* force black background */

    do
    {
        /* Wait for display to be available, then lock it. */
        WaitForSingleObject( hScreenMutex, INFINITE );

        /* If we still occupy the old screen position, blank it out. */
        ReadConsoleOutputCharacter( hConsoleOut, &OldCell, 1, Old, &Dummy );
        ReadConsoleOutputAttribute( hConsoleOut, &OldAttrib, 1, Old, &Dummy );
        if (( OldCell == MyCell ) && (OldAttrib == MyAttrib))
            WriteConsoleOutputCharacter( hConsoleOut, &BlankCell, 1, Old, &Dummy );

        /* Draw new face, then clear screen lock */
        WriteConsoleOutputCharacter( hConsoleOut, &MyCell, 1, Coords, &Dummy );
        WriteConsoleOutputAttribute( hConsoleOut, &MyAttrib, 1, Coords, &Dummy );
        ReleaseMutex( hScreenMutex );

        /* Increment the coordinates for next placement of the block. */
        Old.X = Coords.X;
        Old.Y = Coords.Y;
        Coords.X += Delta.X;
        Coords.Y += Delta.Y;

        /* If we are about to go off the screen, reverse direction */
        if( Coords.X < 0 || Coords.X >= csbiInfo.dwSize.X )
        {
            Delta.X = -Delta.X;
            Beep( 400, 50 );
        }
        if( Coords.Y < 0 || Coords.Y > csbiInfo.dwSize.Y )
        {
            Delta.Y = -Delta.Y;
            Beep( 600, 50 );
        }
    }
    /* Repeat while RunMutex is still taken. */
    while ( WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT );
}

void WriteTitle( int ThreadNum )
{
    char    NThreadMsg[80];

    sprintf( NThreadMsg, "Threads running: %02d.  Press 'A' to start a thread,'Q' to quit.", ThreadNum );
    SetConsoleTitle( NThreadMsg );
}

void ClearScreen( void )
{
    DWORD   dummy;
    COORD   Home = { 0, 0 };
    FillConsoleOutputCharacter( hConsoleOut, ' ', csbiInfo.dwSize.X * csbiInfo.dwSize.Y, Home, &dummy );
}
赵4老师 2015-10-19
  • 打赏
  • 举报
回复
仅供参考:
#include <windows.h>
#include <stdio.h>

void ConPrint(char *CharBuffer, int len);
void ConPrintAt(int x, int y, char *CharBuffer, int len);
void gotoXY(int x, int y);
void ClearConsole(void);
void ClearConsoleToColors(int ForgC, int BackC);
void SetColorAndBackground(int ForgC, int BackC);
void SetColor(int ForgC);
void HideTheCursor(void);
void ShowTheCursor(void);

int main(int argc, char* argv[])
{
   HideTheCursor();
   ClearConsoleToColors(15, 1);
   ClearConsole();
   gotoXY(1, 1);
   SetColor(14);
   printf("This is a test...\n");
   Sleep(5000);
   ShowTheCursor();
   SetColorAndBackground(15, 12);
   ConPrint("This is also a test...\n", 23);
   SetColorAndBackground(1, 7);
   ConPrintAt(22, 15, "This is also a test...\n", 23);
   gotoXY(0, 24);
   SetColorAndBackground(7, 1);
   return 0;
}

//This will clear the console while setting the forground and
//background colors.
void ClearConsoleToColors(int ForgC, int BackC)
{
   WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
   //Get the handle to the current output buffer...
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   //This is used to reset the carat/cursor to the top left.
   COORD coord = {0, 0};
   //A return value... indicating how many chars were written
   //not used but we need to capture this since it will be
   //written anyway (passing NULL causes an access violation).
   DWORD count;

   //This is a structure containing all of the console info
   // it is used here to find the size of the console.
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   //Here we will set the current color
   SetConsoleTextAttribute(hStdOut, wColor);
   if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
   {
      //This fills the buffer with a given character (in this case 32=space).
      FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);

      FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
      //This will set our cursor position for the next print statement.
      SetConsoleCursorPosition(hStdOut, coord);
   }
}

//This will clear the console.
void ClearConsole()
{
   //Get the handle to the current output buffer...
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   //This is used to reset the carat/cursor to the top left.
   COORD coord = {0, 0};
   //A return value... indicating how many chars were written
   //   not used but we need to capture this since it will be
   //   written anyway (passing NULL causes an access violation).
   DWORD count;
   //This is a structure containing all of the console info
   // it is used here to find the size of the console.
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   //Here we will set the current color
   if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
   {
      //This fills the buffer with a given character (in this case 32=space).
      FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
      FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
      //This will set our cursor position for the next print statement.
      SetConsoleCursorPosition(hStdOut, coord);
   }
}

//This will set the position of the cursor
void gotoXY(int x, int y)
{
   //Initialize the coordinates
   COORD coord = {x, y};
   //Set the position
   SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

//This will set the forground color for printing in a console window.
void SetColor(int ForgC)
{
   WORD wColor;
   //We will need this handle to get the current background attribute
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   CONSOLE_SCREEN_BUFFER_INFO csbi;

   //We use csbi for the wAttributes word.
   if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
   {
      //Mask out all but the background attribute, and add in the forgournd color
      wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);
      SetConsoleTextAttribute(hStdOut, wColor);
   }
}

//This will set the forground and background color for printing in a console window.
void SetColorAndBackground(int ForgC, int BackC)
{
   WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;
   SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
}

//Direct console output
void ConPrint(char *CharBuffer, int len)
{
   DWORD count;
   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), CharBuffer, len, &count, NULL);
}

//Direct Console output at a particular coordinate.
void ConPrintAt(int x, int y, char *CharBuffer, int len)
{
   DWORD count;
   COORD coord = {x, y};
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   SetConsoleCursorPosition(hStdOut, coord);
   WriteConsole(hStdOut, CharBuffer, len, &count, NULL);
}

//Hides the console cursor
void HideTheCursor()
{
   CONSOLE_CURSOR_INFO cciCursor;
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

   if(GetConsoleCursorInfo(hStdOut, &cciCursor))
   {
      cciCursor.bVisible = FALSE;
	  SetConsoleCursorInfo(hStdOut, &cciCursor);
   }
}

//Shows the console cursor
void ShowTheCursor()
{
   CONSOLE_CURSOR_INFO cciCursor;
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

   if(GetConsoleCursorInfo(hStdOut, &cciCursor))
   {
      cciCursor.bVisible = TRUE;
	  SetConsoleCursorInfo(hStdOut, &cciCursor);
   }
}

laoshizhuce 2015-10-19
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
[/code]
哥 你的程序我跑了下 打印不是固定的几行 而是一直刷屏 谢谢你帮忙 $ ./a.out 2015-10-19 11:09:38.475 Start=========================================================== 2015-10-19 11:09:38.476 002 thdB thread begin... 2015-10-19 11:09:38.478 001 thdA thread begin... 2015-10-19 11:09:38.579 001 sending 200 bytes 2015-10-19 11:09:38.579 001 0000 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.579 001 0010 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.579 001 0020 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.580 001 0030 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.580 001 0040 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.580 001 0050 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.580 001 0060 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.580 001 0070 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.580 001 0080 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.580 001 0090 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.580 001 00a0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 00b0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 00c0 - 00 00 00 00 00 00 00 00 ........ 2015-10-19 11:09:38.581 001 sent 200 bytes 2015-10-19 11:09:38.581 001 0000 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 0010 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 0020 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 0030 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 0040 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 0050 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 0060 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 0070 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 0080 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 0090 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 00a0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.581 001 00b0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2015-10-19 11:09:38.582 001 00c0 - 00 00 00 00 00 00 00 00 ........ 2015-10-19 11:09:38.682 001 sending 200 bytes 2015-10-19 11:09:38.682 001 0000 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.683 001 0010 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.683 001 0020 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.683 001 0030 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.685 001 0040 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.685 001 0050 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.685 001 0060 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.686 001 0070 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.686 001 0080 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.686 001 0090 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.686 001 00a0 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.686 001 00b0 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.686 001 00c0 - 01 01 01 01 01 01 01 01 ........ 2015-10-19 11:09:38.686 001 sent 40 bytes 2015-10-19 11:09:38.686 001 0000 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.687 001 0010 - 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................ 2015-10-19 11:09:38.687 001 0020 - 01 01 01 01 01 01 01 01 ........ 2015-10-19 11:09:39.492 002 recv 2 bytes 2015-10-19 11:09:39.492 002 0000 - 00 00 .. 2015-10-19 11:09:39.494 002 recv 2 bytes 2015-10-19 11:09:39.494 002 0000 - 00 00 .. 2015-10-19 11:09:39.495 002 recv 2 bytes 2015-10-19 11:09:39.496 002 0000 - 00 00 .. 2015-10-19 11:09:39.497 002 recv 2 bytes 2015-10-19 11:09:39.498 002 0000 - 00 00 .. 2015-10-19 11:09:39.499 002 recv 2 bytes 2015-10-19 11:09:39.499 002 0000 - 00 00 .. 2015-10-19 11:09:39.501 002 recv 2 bytes 2015-10-19 11:09:39.501 002 0000 - 00 00 .. 2015-10-19 11:09:39.503 002 recv 2 bytes 2015-10-19 11:09:39.503 002 0000 - 00 00 ..
Saleayas 2015-10-19
  • 打赏
  • 举报
回复
// 清除屏幕 05.#define CLEAR() printf("\033[2J") 06. 07.// 上移光标 08.#define MOVEUP(x) printf("\033[%dA", (x)) 09. 10.// 下移光标 11.#define MOVEDOWN(x) printf("\033[%dB", (x)) 12. 13.// 左移光标 14.#define MOVELEFT(y) printf("\033[%dD", (y)) 15. 16.// 右移光标 17.#define MOVERIGHT(y) printf("\033[%dC",(y)) 18. 19.// 定位光标 20.#define MOVETO(x,y) printf("\033[%d;%dH", (x), (y)) 21. 22.// 光标复位 23.#define RESET_CURSOR() printf("\033[H") 24. 25.// 隐藏光标 26.#define HIDE_CURSOR() printf("\033[?25l") 27. 28.// 显示光标 29.#define SHOW_CURSOR() printf("\033[?25h") 30. 31.//反显 32.#define HIGHT_LIGHT() printf("\033[7m") 33.#define UN_HIGHT_LIGHT() printf("\033[27m") linux 下试试这个,我上大学的时候,玩 Mud 时印象最深了。还支持颜色的。
赵4老师 2015-10-19
  • 打赏
  • 举报
回复
仅供参考:
//循环向a函数每次发送200个字节长度(这个是固定的)的buffer,
//a函数中需要将循环传进来的buffer,组成240字节(也是固定的)的新buffer进行处理,
//在处理的时候每次从新buffer中取两个字节打印
#ifdef WIN32
    #pragma warning(disable:4996)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
    #include <windows.h>
    #include <process.h>
    #include <io.h>
    #define  MYVOID             void
    #define  vsnprintf          _vsnprintf
#else
    #include <unistd.h>
    #include <sys/time.h>
    #include <pthread.h>
    #define  CRITICAL_SECTION   pthread_mutex_t
    #define  MYVOID             void *
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
    EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
    LeaveCriticalSection(l);
}
void sleep_ms(int ms) {
    Sleep(ms);
}
#else
void Lock(CRITICAL_SECTION *l) {
    pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
    pthread_mutex_unlock(l);
}
void sleep_ms(int ms) {
    usleep(ms*1000);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
    struct tm *now;
    struct timeb tb;

    if (NULL==pszFmt||0==pszFmt[0]) return;
    vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
    ftime(&tb);
    now=localtime(&tb.time);
    sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
    sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );
    sprintf(mss,"%03d",tb.millitm);
    printf("%s %s.%s %s",datestr,timestr,mss,logstr);
    flog=fopen(logfilename1,"a");
    if (NULL!=flog) {
        fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
        if (ftell(flog)>MAXLOGSIZE) {
            fclose(flog);
            if (rename(logfilename1,logfilename2)) {
                remove(logfilename2);
                rename(logfilename1,logfilename2);
            }
        } else {
            fclose(flog);
        }
    }
}
void Log(const char *pszFmt,...) {
    va_list argp;

    Lock(&cs_log);
    va_start(argp,pszFmt);
    LogV(pszFmt,argp);
    va_end(argp);
    Unlock(&cs_log);
}
//Log}
#define ASIZE    200
#define BSIZE    240
#define CSIZE      2
char Abuf[ASIZE];
char Cbuf[CSIZE];
CRITICAL_SECTION cs_HEX ;
CRITICAL_SECTION cs_BBB ;
struct FIFO_BUFFER {
    int  head;
    int  tail;
    int  size;
    char data[BSIZE];
} BBB;
int No_Loop=0;
void HexDump(int cn,char *buf,int len) {
    int i,j,k;
    char binstr[80];

    Lock(&cs_HEX);
    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%03d %04x -",cn,i);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            Log("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        Log("%s\n",binstr);
    }
    Unlock(&cs_HEX);
}
int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
    int lent,len1,len2;

    lent=0;
    Lock(cs);
    if (fbuf->size>=len) {
        lent=len;
        if (fbuf->head+lent>BSIZE) {
            len1=BSIZE-fbuf->head;
            memcpy(buf     ,fbuf->data+fbuf->head,len1);
            len2=lent-len1;
            memcpy(buf+len1,fbuf->data           ,len2);
            fbuf->head=len2;
        } else {
            memcpy(buf     ,fbuf->data+fbuf->head,lent);
            fbuf->head+=lent;
        }
        fbuf->size-=lent;
    }
    Unlock(cs);
    return lent;
}
MYVOID thdB(void *pcn) {
    char        *recv_buf;
    int          recv_nbytes;
    int          cn;
    int          wc;
    int          pb;

    cn=(int)pcn;
    Log("%03d thdB              thread begin...\n",cn);
    while (1) {
        sleep_ms(10);
        recv_buf=(char *)Cbuf;
        recv_nbytes=CSIZE;
        wc=0;
        while (1) {
            pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);
            if (pb) {
                Log("%03d recv %d bytes\n",cn,pb);
                HexDump(cn,recv_buf,pb);
                sleep_ms(1);
            } else {
                sleep_ms(1000);
            }
            if (No_Loop) break;//
            wc++;
            if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
        }
        if (No_Loop) break;//
    }
#ifndef WIN32
    pthread_exit(NULL);
#endif
}
int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
    int lent,len1,len2;

    Lock(cs);
    lent=len;
    if (fbuf->size+lent>BSIZE) {
        lent=BSIZE-fbuf->size;
    }
    if (fbuf->tail+lent>BSIZE) {
        len1=BSIZE-fbuf->tail;
        memcpy(fbuf->data+fbuf->tail,buf     ,len1);
        len2=lent-len1;
        memcpy(fbuf->data           ,buf+len1,len2);
        fbuf->tail=len2;
    } else {
        memcpy(fbuf->data+fbuf->tail,buf     ,lent);
        fbuf->tail+=lent;
    }
    fbuf->size+=lent;
    Unlock(cs);
    return lent;
}
MYVOID thdA(void *pcn) {
    char        *send_buf;
    int          send_nbytes;
    int          cn;
    int          wc;
    int           a;
    int          pa;

    cn=(int)pcn;
    Log("%03d thdA              thread begin...\n",cn);
    a=0;
    while (1) {
        sleep_ms(100);
        memset(Abuf,a,ASIZE);
        a=(a+1)%256;
        if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop
        send_buf=(char *)Abuf;
        send_nbytes=ASIZE;
        Log("%03d sending %d bytes\n",cn,send_nbytes);
        HexDump(cn,send_buf,send_nbytes);
        wc=0;
        while (1) {
            pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);
            Log("%03d sent %d bytes\n",cn,pa);
            HexDump(cn,send_buf,pa);
            send_buf+=pa;
            send_nbytes-=pa;
            if (send_nbytes<=0) break;//
            sleep_ms(1000);
            if (No_Loop) break;//
            wc++;
            if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
        }
        if (No_Loop) break;//
    }
#ifndef WIN32
    pthread_exit(NULL);
#endif
}
int main() {
#ifdef WIN32
    InitializeCriticalSection(&cs_log);
    InitializeCriticalSection(&cs_HEX );
    InitializeCriticalSection(&cs_BBB );
#else
    pthread_t threads[2];
    int threadsN;
    int rc;
    pthread_mutex_init(&cs_log,NULL);
    pthread_mutex_init(&cs_HEX,NULL);
    pthread_mutex_init(&cs_BBB,NULL);
#endif
    Log("Start===========================================================\n");

    BBB.head=0;
    BBB.tail=0;
    BBB.size=0;

#ifdef WIN32
    _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);
    _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2);
#else
    threadsN=0;
    rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
    rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
#endif

    if (!access("No_Loop",0)) {
        remove("No_Loop");
        if (!access("No_Loop",0)) {
            No_Loop=1;
        }
    }
    while (1) {
        sleep_ms(1000);
        if (No_Loop) break;//
        if (!access("No_Loop",0)) {
            No_Loop=1;
        }
    }
    sleep_ms(3000);
    Log("End=============================================================\n");
#ifdef WIN32
    DeleteCriticalSection(&cs_BBB );
    DeleteCriticalSection(&cs_HEX );
    DeleteCriticalSection(&cs_log);
#else
    pthread_mutex_destroy(&cs_BBB);
    pthread_mutex_destroy(&cs_HEX);
    pthread_mutex_destroy(&cs_log);
#endif
    return 0;
}
laoshizhuce 2015-10-19
  • 打赏
  • 举报
回复
谢谢楼上回答 不好意思是 linux环境下 我有尝试使用退格键,发现没有作用
Saleayas 2015-10-19
  • 打赏
  • 举报
回复
使用控制台函数来实现位置和颜色之类的。 诸如 SetConsoleCursorPosition
赵4老师 2015-10-19
  • 打赏
  • 举报
回复
引用 15 楼 laoshizhuce 的回复:
[quote=引用 14 楼 paschen 的回复:] [quote=引用 11 楼 laoshizhuce 的回复:] [quote=引用 9 楼 paschen 的回复:] 各线程自已获得信息,输出到控制台就行了,输出的时候记得加锁(比如使用临界区)
如果只是输出 比较好办 主要是要将log控制在一行 每个线程一行 您有什么好办法没有[/quote] 每个线程定位输出的位置,可以这样: COORD cd; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cd); //将光标移动到cd位置 cout<<xxxxxx; //输出 其中cd就是输出位置的坐标(x,y)[/quote] 谢谢回答 跟我想象的有些落差 可以单纯使用printf做到吗 谢谢[/quote] 搜“ANSI.SYS” http://baike.baidu.com/link?url=mLzIvG59DyikMD5pUb1zVBa0fvK-xoAsaNILdrDKzA_ArOmgqa-xUaCHrtygZmpvZ5VmqleS-3dB-bvEMwuVLa
paschen 版主 2015-10-19
  • 打赏
  • 举报
回复
引用 15 楼 laoshizhuce 的回复:
[quote=引用 14 楼 paschen 的回复:] [quote=引用 11 楼 laoshizhuce 的回复:] [quote=引用 9 楼 paschen 的回复:] 各线程自已获得信息,输出到控制台就行了,输出的时候记得加锁(比如使用临界区)
如果只是输出 比较好办 主要是要将log控制在一行 每个线程一行 您有什么好办法没有[/quote] 每个线程定位输出的位置,可以这样: COORD cd; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cd); //将光标移动到cd位置 cout<<xxxxxx; //输出 其中cd就是输出位置的坐标(x,y)[/quote] 谢谢回答 跟我想象的有些落差 可以单纯使用printf做到吗 谢谢[/quote] 一样要在输出前先SetConsoleCursorPosition改变光标位置,然后printf啊 每个线程记录自己应输出的位置
laoshizhuce 2015-10-19
  • 打赏
  • 举报
回复
引用 14 楼 paschen 的回复:
[quote=引用 11 楼 laoshizhuce 的回复:] [quote=引用 9 楼 paschen 的回复:] 各线程自已获得信息,输出到控制台就行了,输出的时候记得加锁(比如使用临界区)
如果只是输出 比较好办 主要是要将log控制在一行 每个线程一行 您有什么好办法没有[/quote] 每个线程定位输出的位置,可以这样: COORD cd; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cd); //将光标移动到cd位置 cout<<xxxxxx; //输出 其中cd就是输出位置的坐标(x,y)[/quote] 谢谢回答 跟我想象的有些落差 可以单纯使用printf做到吗 谢谢
paschen 版主 2015-10-19
  • 打赏
  • 举报
回复
引用 11 楼 laoshizhuce 的回复:
[quote=引用 9 楼 paschen 的回复:] 各线程自已获得信息,输出到控制台就行了,输出的时候记得加锁(比如使用临界区)
如果只是输出 比较好办 主要是要将log控制在一行 每个线程一行 您有什么好办法没有[/quote] 每个线程定位输出的位置,可以这样: COORD cd; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cd); //将光标移动到cd位置 cout<<xxxxxx; //输出 其中cd就是输出位置的坐标(x,y)
laoshizhuce 2015-10-19
  • 打赏
  • 举报
回复
引用 12 楼 zhao4zhong1 的回复:
[quote=引用 10 楼 zhao4zhong1 的回复:] Linux下参考NCURSES库。
http://skyishuman.iteye.com/blog/1672476 [/quote] 谢谢您的回答 可以不借助curese库, 单纯使用printf可以做到吗 因为我不想对屏幕的其他字符有太多影响 谢谢
赵4老师 2015-10-19
  • 打赏
  • 举报
回复
引用 10 楼 zhao4zhong1 的回复:
Linux下参考NCURSES库。
http://skyishuman.iteye.com/blog/1672476
laoshizhuce 2015-10-19
  • 打赏
  • 举报
回复
引用 9 楼 paschen 的回复:
各线程自已获得信息,输出到控制台就行了,输出的时候记得加锁(比如使用临界区)
如果只是输出 比较好办 主要是要将log控制在一行 每个线程一行 您有什么好办法没有
赵4老师 2015-10-19
  • 打赏
  • 举报
回复
Linux下参考NCURSES库。
paschen 版主 2015-10-19
  • 打赏
  • 举报
回复
各线程自已获得信息,输出到控制台就行了,输出的时候记得加锁(比如使用临界区)
加载更多回复(1)

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧