Skip to content

System.ArgumentOutOfRangeException #5046

@gycog

Description

@gycog

Prerequisites

  • Write a descriptive title.
  • Make sure you are able to repro it on the latest released version
  • Search the existing issues, especially the pinned issues.

Exception report

gcc -o ping_single_instance.exe src/single_instance_ping.c -lws2_32 && & .\ping_single_ins
哎呀,出现问题。请在报告此 Bug 时添加以下详细信息。
在 GitHub 上报告: https://github.com/lzybkr/PSReadLine/issues/new  
-----------------------------------------------------------------------
上 200 个密钥:
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Enter
 Enter
 & Space . \ p i n g _ s i n g l e _ i n s t a n c e . e x e Enter 
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Space & & Space & Space . \ p i n g _ s i n g l e 
_ i n s t a n c e . e x e Enter


异常:
System.ArgumentOutOfRangeException: 该值必须大于或等于零,且必须小于控制台缓冲区在该维度的大小。
参数名: top
实际值是 -1。
   在 System.Console.SetCursorPosition(Int32 left, Int32 top)      
   在 Microsoft.PowerShell.PSConsoleReadLine.ReallyRender(RenderData renderData, String defaultColor)
   在 Microsoft.PowerShell.PSConsoleReadLine.ForceRender()
   在 Microsoft.PowerShell.PSConsoleReadLine.Insert(Char c)        
   在 Microsoft.PowerShell.PSConsoleReadLine.SelfInsert(Nullable`1 
key, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(ConsoleKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   在 Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------
(TraeAI-3) D:\ping_project [0:0] $ gcc -o ping_single_instance.exe src/single_instance_ping.c -lws2_32 && & .\ping_single_inst
哎呀,出现问题。请在报告此 Bug 时添加以下详细信息。
在 GitHub 上报告: https://github.com/lzybkr/PSReadLine/issues/new  
-----------------------------------------------------------------------
上 200 个密钥:
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Enter
 Enter
 & Space . \ p i n g _ s i n g l e _ i n s t a n c e . e x e Enter 
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Space & & Space & Space . \ p i n g _ s i n g l e 
_ i n s t a n c e . e x e Enter
 Enter


异常:
System.ArgumentOutOfRangeException: 该值必须大于或等于零,且必须小于控制台缓冲区在该维度的大小。
参数名: top
实际值是 -1。
   在 System.Console.SetCursorPosition(Int32 left, Int32 top)      
   在 Microsoft.PowerShell.PSConsoleReadLine.ReallyRender(RenderData renderData, String defaultColor)
   在 Microsoft.PowerShell.PSConsoleReadLine.ForceRender()
   在 Microsoft.PowerShell.PSConsoleReadLine.Insert(Char c)        
   在 Microsoft.PowerShell.PSConsoleReadLine.SelfInsert(Nullable`1 
key, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(ConsoleKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   在 Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------
(TraeAI-3) D:\ping_project [0:0] $ gcc -o ping_single_instance.exe src/single_instance_ping.c -lws2_32 && & .\ping_single_insta
哎呀,出现问题。请在报告此 Bug 时添加以下详细信息。
在 GitHub 上报告: https://github.com/lzybkr/PSReadLine/issues/new  
-----------------------------------------------------------------------
上 200 个密钥:
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Enter
 Enter
 & Space . \ p i n g _ s i n g l e _ i n s t a n c e . e x e Enter 
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Space & & Space & Space . \ p i n g _ s i n g l e 
_ i n s t a n c e . e x e Enter
 Enter


异常:
System.ArgumentOutOfRangeException: 该值必须大于或等于零,且必须小于控制台缓冲区在该维度的大小。
参数名: top
实际值是 -1。
   在 System.Console.SetCursorPosition(Int32 left, Int32 top)      
   在 Microsoft.PowerShell.PSConsoleReadLine.ReallyRender(RenderData renderData, String defaultColor)
   在 Microsoft.PowerShell.PSConsoleReadLine.ForceRender()
   在 Microsoft.PowerShell.PSConsoleReadLine.Insert(Char c)        
   在 Microsoft.PowerShell.PSConsoleReadLine.SelfInsert(Nullable`1 
key, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(ConsoleKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   在 Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------
(TraeAI-3) D:\ping_project [0:0] $ gcc -o ping_single_instance.exe src/single_instance_ping.c -lws2_32 && & .\ping_single_instan
哎呀,出现问题。请在报告此 Bug 时添加以下详细信息。
在 GitHub 上报告: https://github.com/lzybkr/PSReadLine/issues/new  
-----------------------------------------------------------------------
上 200 个密钥:
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Enter
 Enter
 & Space . \ p i n g _ s i n g l e _ i n s t a n c e . e x e Enter 
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Space & & Space & Space . \ p i n g _ s i n g l e 
_ i n s t a n c e . e x e Enter
 Enter


异常:
System.ArgumentOutOfRangeException: 该值必须大于或等于零,且必须小于控制台缓冲区在该维度的大小。
参数名: top
实际值是 -1。
   在 System.Console.SetCursorPosition(Int32 left, Int32 top)      
   在 Microsoft.PowerShell.PSConsoleReadLine.ReallyRender(RenderData renderData, String defaultColor)
   在 Microsoft.PowerShell.PSConsoleReadLine.ForceRender()
   在 Microsoft.PowerShell.PSConsoleReadLine.Insert(Char c)        
   在 Microsoft.PowerShell.PSConsoleReadLine.SelfInsert(Nullable`1 
key, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(ConsoleKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   在 Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------
(TraeAI-3) D:\ping_project [0:0] $ gcc -o ping_single_instance.exe src/single_instance_ping.c -lws2_32 && & .\ping_single_instanc
哎呀,出现问题。请在报告此 Bug 时添加以下详细信息。
在 GitHub 上报告: https://github.com/lzybkr/PSReadLine/issues/new  
-----------------------------------------------------------------------
上 200 个密钥:
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Enter
 Enter
 & Space . \ p i n g _ s i n g l e _ i n s t a n c e . e x e Enter 
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Space & & Space & Space . \ p i n g _ s i n g l e 
_ i n s t a n c e . e x e Enter
 Enter


异常:
System.ArgumentOutOfRangeException: 该值必须大于或等于零,且必须小于控制台缓冲区在该维度的大小。
参数名: top
实际值是 -1。
   在 System.Console.SetCursorPosition(Int32 left, Int32 top)      
   在 Microsoft.PowerShell.PSConsoleReadLine.ReallyRender(RenderData renderData, String defaultColor)
   在 Microsoft.PowerShell.PSConsoleReadLine.ForceRender()
   在 Microsoft.PowerShell.PSConsoleReadLine.Insert(Char c)        
   在 Microsoft.PowerShell.PSConsoleReadLine.SelfInsert(Nullable`1 
key, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(ConsoleKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   在 Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------
(TraeAI-3) D:\ping_project [0:0] $ gcc -o ping_single_instance.exe src/single_instance_ping.c -lws2_32 && & .\ping_single_instance
哎呀,出现问题。请在报告此 Bug 时添加以下详细信息。
在 GitHub 上报告: https://github.com/lzybkr/PSReadLine/issues/new  
-----------------------------------------------------------------------
上 200 个密钥:
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Enter
 Enter
 & Space . \ p i n g _ s i n g l e _ i n s t a n c e . e x e Enter
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Space & & Space & Space . \ p i n g _ s i n g l e 
_ i n s t a n c e . e x e Enter
 Enter


异常:
System.ArgumentOutOfRangeException: 该值必须大于或等于零,且必须小于控制台缓冲区在该维度的大小。
参数名: top
实际值是 -1。
   在 System.Console.SetCursorPosition(Int32 left, Int32 top)      
   在 Microsoft.PowerShell.PSConsoleReadLine.ReallyRender(RenderData renderData, String defaultColor)
   在 Microsoft.PowerShell.PSConsoleReadLine.ForceRender()
   在 Microsoft.PowerShell.PSConsoleReadLine.Insert(Char c)        
   在 Microsoft.PowerShell.PSConsoleReadLine.SelfInsert(Nullable`1 
key, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(ConsoleKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   在 Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------
(TraeAI-3) D:\ping_project [0:0] $ gcc -o ping_single_instance.exe src/single_instance_ping.c -lws2_32 && & .\ping_single_instance.
哎呀,出现问题。请在报告此 Bug 时添加以下详细信息。
在 GitHub 上报告: https://github.com/lzybkr/PSReadLine/issues/new  
-----------------------------------------------------------------------
上 200 个密钥:
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Enter
 Enter
 & Space . \ p i n g _ s i n g l e _ i n s t a n c e . e x e Enter 
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Space & & Space & Space . \ p i n g _ s i n g l e 
_ i n s t a n c e . e x e Enter
 Enter


异常:
System.ArgumentOutOfRangeException: 该值必须大于或等于零,且必须小于控制台缓冲区在该维度的大小。
参数名: top
实际值是 -1。
   在 System.Console.SetCursorPosition(Int32 left, Int32 top)      
   在 Microsoft.PowerShell.PSConsoleReadLine.ReallyRender(RenderData renderData, String defaultColor)
   在 Microsoft.PowerShell.PSConsoleReadLine.ForceRender()
   在 Microsoft.PowerShell.PSConsoleReadLine.Insert(Char c)        
   在 Microsoft.PowerShell.PSConsoleReadLine.SelfInsert(Nullable`1 
key, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(ConsoleKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   在 Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------
(TraeAI-3) D:\ping_project [0:0] $ gcc -o ping_single_instance.exe src/single_instance_ping.c -lws2_32 && & .\ping_single_instance.e
哎呀,出现问题。请在报告此 Bug 时添加以下详细信息。
在 GitHub 上报告: https://github.com/lzybkr/PSReadLine/issues/new  
-----------------------------------------------------------------------
上 200 个密钥:
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Enter
 Enter
 & Space . \ p i n g _ s i n g l e _ i n s t a n c e . e x e Enter 
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Space & & Space & Space . \ p i n g _ s i n g l e 
_ i n s t a n c e . e x e Enter
 Enter


异常:
System.ArgumentOutOfRangeException: 该值必须大于或等于零,且必须小于控制台缓冲区在该维度的大小。
参数名: top
实际值是 -1。
   在 System.Console.SetCursorPosition(Int32 left, Int32 top)      
   在 Microsoft.PowerShell.PSConsoleReadLine.ReallyRender(RenderData renderData, String defaultColor)
   在 Microsoft.PowerShell.PSConsoleReadLine.ForceRender()
   在 Microsoft.PowerShell.PSConsoleReadLine.Insert(Char c)        
   在 Microsoft.PowerShell.PSConsoleReadLine.SelfInsert(Nullable`1 
key, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(ConsoleKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   在 Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------
(TraeAI-3) D:\ping_project [0:0] $ gcc -o ping_single_instance.exe src/single_instance_ping.c -lws2_32 && & .\ping_single_instance.ex
哎呀,出现问题。请在报告此 Bug 时添加以下详细信息。
在 GitHub 上报告: https://github.com/lzybkr/PSReadLine/issues/new  
-----------------------------------------------------------------------
上 200 个密钥:
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Enter
 Enter
 & Space . \ p i n g _ s i n g l e _ i n s t a n c e . e x e Enter 
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Space & & Space & Space . \ p i n g _ s i n g l e 
_ i n s t a n c e . e x e Enter
 Enter


异常:
System.ArgumentOutOfRangeException: 该值必须大于或等于零,且必须小于控制台缓冲区在该维度的大小。
参数名: top
实际值是 -1。
   在 System.Console.SetCursorPosition(Int32 left, Int32 top)      
   在 Microsoft.PowerShell.PSConsoleReadLine.ReallyRender(RenderData renderData, String defaultColor)
   在 Microsoft.PowerShell.PSConsoleReadLine.ForceRender()
   在 Microsoft.PowerShell.PSConsoleReadLine.Insert(Char c)        
   在 Microsoft.PowerShell.PSConsoleReadLine.SelfInsert(Nullable`1 
key, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(ConsoleKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   在 Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------
(TraeAI-3) D:\ping_project [0:0] $ gcc -o ping_single_instance.exe src/single_instance_ping.c -lws2_32 && & .\ping_single_instance.exe
哎呀,出现问题。请在报告此 Bug 时添加以下详细信息。
在 GitHub 上报告: https://github.com/lzybkr/PSReadLine/issues/new  
-----------------------------------------------------------------------
上 200 个密钥:
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Enter
 Enter
 & Space . \ p i n g _ s i n g l e _ i n s t a n c e . e x e Enter 
 Enter
 g c c Space - o Space p i n g _ s i n g l e _ i n s t a n c e . e 
x e Space s r c / s i n g l e _ i n s t a n c e _ p i n g . c Space - l w s 2 _ 3 2 Space & & Space & Space . \ p i n g _ s i n g l e 
_ i n s t a n c e . e x e Enter
 Enter


异常:
System.ArgumentOutOfRangeException: 该值必须大于或等于零,且必须小于控制台缓冲区在该维度的大小。
参数名: top
实际值是 -1。
   在 System.Console.SetCursorPosition(Int32 left, Int32 top)      
   在 Microsoft.PowerShell.PSConsoleReadLine.ReallyRender(RenderData renderData, String defaultColor)
   在 Microsoft.PowerShell.PSConsoleReadLine.ForceRender()
   在 Microsoft.PowerShell.PSConsoleReadLine.AcceptLineImpl(Boolean validate)
   在 Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(ConsoleKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   在 Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   在 Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
-----------------------------------------------------------------------
(TraeAI-3) D:\ping_project [0:0] $ gcc -o ping_single_instance.exe src/single_instance_ping.c -lws所在位置 行:1 字符: 69
+ ... ng_single_instance.exe src/single_instance_ping.c -lws2_32 & 
& & .\pin ...
+                                                                ~ 
~
标记“&&”不是此版本中的有效语句分隔符。
    + CategoryInfo          : ParserError: (:) [], ParentContains  
   ErrorRecordException
    + FullyQualifiedErrorId : InvalidEndOfLine

Screenshot

N/A

Environment data

PS Version: 5.1.19041.6691
PS HostName: ConsoleHost
PSReadLine Version: 2.0.0-beta2
PSReadLine EditMode: Windows
OS: 10.0.19041.4522 (WinBuild.160101.0800)
BufferWidth: 120
BufferHeight: 3000

Steps to reproduce

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

static HANDLE g_mutex = NULL;
static FILE* g_log = NULL;
static CRITICAL_SECTION g_cs;

// 函数声明
static void format_timestamp(char* buf, size_t sz);
static void log_line(const char* tag, const char* msg);
static int utf8_to_acp(const char* utf8_str, char* acp_str, int acp_size);
static int acp_to_utf8(const char* acp_str, char* utf8_str, int utf8_size);

// 线程池相关定义
#define MAX_THREADS 4

// 任务结构体
typedef struct {
int task_id;
char target[64]; // ping的目标地址
int count; // ping的次数
} Task;

// 线程池结构体
typedef struct {
HANDLE threads[MAX_THREADS];
HANDLE task_queue_sem;
HANDLE task_queue_mutex;
HANDLE stop_event;
Task* task_queue;
int queue_size;
int queue_front;
int queue_rear;
int task_count;
int total_tasks; // 总任务数
int completed_tasks; // 已完成任务数
HANDLE completed_tasks_mutex;
} ThreadPool;

static ThreadPool g_thread_pool;

// 初始化线程池
static BOOL init_thread_pool(int queue_size) {
memset(&g_thread_pool, 0, sizeof(g_thread_pool));

g_thread_pool.queue_size = queue_size;
g_thread_pool.task_queue = (Task*)malloc(queue_size * sizeof(Task));
if (!g_thread_pool.task_queue) {
    log_line("main", "failed to allocate task queue");
    return FALSE;
}

// 创建信号量和互斥量
g_thread_pool.task_queue_sem = CreateSemaphoreA(NULL, 0, queue_size, NULL);
g_thread_pool.task_queue_mutex = CreateMutexA(NULL, FALSE, NULL);
g_thread_pool.stop_event = CreateEventA(NULL, TRUE, FALSE, NULL);
g_thread_pool.completed_tasks_mutex = CreateMutexA(NULL, FALSE, NULL);

if (!g_thread_pool.task_queue_sem || !g_thread_pool.task_queue_mutex || 
    !g_thread_pool.stop_event || !g_thread_pool.completed_tasks_mutex) {
    log_line("main", "failed to create thread pool synchronization objects");
    free(g_thread_pool.task_queue);
    return FALSE;
}

g_thread_pool.total_tasks = 0;
g_thread_pool.completed_tasks = 0;

return TRUE;

}

// 销毁线程池
static void destroy_thread_pool() {
SetEvent(g_thread_pool.stop_event);

// 等待所有线程结束
WaitForMultipleObjects(MAX_THREADS, g_thread_pool.threads, TRUE, INFINITE);

// 关闭句柄
for (int i = 0; i < MAX_THREADS; i++) {
    if (g_thread_pool.threads[i]) {
        CloseHandle(g_thread_pool.threads[i]);
    }
}

CloseHandle(g_thread_pool.task_queue_sem);
CloseHandle(g_thread_pool.task_queue_mutex);
CloseHandle(g_thread_pool.stop_event);
CloseHandle(g_thread_pool.completed_tasks_mutex);

// 释放任务队列
free(g_thread_pool.task_queue);

}

// 添加任务到线程池
static BOOL add_task_to_pool(int task_id, const char* target, int count) {
WaitForSingleObject(g_thread_pool.task_queue_mutex, INFINITE);

// 检查队列是否已满
if (g_thread_pool.task_count >= g_thread_pool.queue_size) {
    ReleaseMutex(g_thread_pool.task_queue_mutex);
    return FALSE;
}

// 添加任务到队列
Task* task = &g_thread_pool.task_queue[g_thread_pool.queue_rear];
task->task_id = task_id;
strncpy(task->target, target, sizeof(task->target) - 1);
task->count = count;

g_thread_pool.queue_rear = (g_thread_pool.queue_rear + 1) % g_thread_pool.queue_size;
g_thread_pool.task_count++;

ReleaseMutex(g_thread_pool.task_queue_mutex);

// 增加总任务数计数
WaitForSingleObject(g_thread_pool.completed_tasks_mutex, INFINITE);
g_thread_pool.total_tasks++;
ReleaseMutex(g_thread_pool.completed_tasks_mutex);

// 通知工作线程有新任务
ReleaseSemaphore(g_thread_pool.task_queue_sem, 1, NULL);

return TRUE;

}

// 从任务队列中取出任务
static BOOL get_task_from_pool(Task* task) {
DWORD dwResult = WaitForMultipleObjects(2,
(const HANDLE[]){g_thread_pool.stop_event, g_thread_pool.task_queue_sem},
FALSE, INFINITE);

// 检查是否收到停止信号
if (dwResult == WAIT_OBJECT_0) {
    return FALSE;
}

// 检查是否有任务
if (dwResult == WAIT_OBJECT_0 + 1) {
    WaitForSingleObject(g_thread_pool.task_queue_mutex, INFINITE);
    
    // 取出任务
    *task = g_thread_pool.task_queue[g_thread_pool.queue_front];
    g_thread_pool.queue_front = (g_thread_pool.queue_front + 1) % g_thread_pool.queue_size;
    g_thread_pool.task_count--;
    
    ReleaseMutex(g_thread_pool.task_queue_mutex);
    return TRUE;
}

return FALSE;

}

// 工作线程函数
static DWORD WINAPI thread_pool_worker(LPVOID param) {
int thread_idx = (int)(intptr_t)param;
char tag[16];
_snprintf(tag, sizeof(tag), "thread%d", thread_idx);
log_line(tag, "start");

Task task;
while (get_task_from_pool(&task)) {
    // 执行ping任务
    char task_info[128];
    _snprintf(task_info, sizeof(task_info), "task%d: ping %s -n %d", task.task_id, task.target, task.count);
    log_line(tag, task_info);
    
    // 构建ping命令
    char ping_cmd[128];
    _snprintf(ping_cmd, sizeof(ping_cmd), "ping %s -n %d", task.target, task.count);
    
    // 执行ping命令
    FILE* fp = _popen(ping_cmd, "r");
    if (!fp) {
        log_line(tag, "failed to start ping");
        continue;
    }
    char acp_buf[512];
    char utf8_buf[1024];
    while (fgets(acp_buf, sizeof(acp_buf), fp)) {
        size_t len = strlen(acp_buf);
        while (len && (acp_buf[len - 1] == '\n' || acp_buf[len - 1] == '\r')) {
            acp_buf[--len] = '\0';
        }
        
        // 将系统默认编码转换为UTF-8
        if (acp_to_utf8(acp_buf, utf8_buf, sizeof(utf8_buf)) > 0) {
            log_line(tag, utf8_buf);
        } else {
            log_line(tag, acp_buf);
        }
    }
    _pclose(fp);
    log_line(tag, "done");
    
    // 增加已完成任务计数
    WaitForSingleObject(g_thread_pool.completed_tasks_mutex, INFINITE);
    g_thread_pool.completed_tasks++;
    ReleaseMutex(g_thread_pool.completed_tasks_mutex);
}

log_line(tag, "exit");
return 0;

}

static void format_timestamp(char* buf, size_t sz) {
SYSTEMTIME st;
GetLocalTime(&st);
_snprintf(buf, sz, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
}

// 编码转换函数:UTF-8转系统默认编码(用于终端输出)
static int utf8_to_acp(const char* utf8_str, char* acp_str, int acp_size) {
// 获取系统默认代码页
UINT acp_code = GetACP();

// 转换为宽字符
int len = MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1, NULL, 0);
if (len <= 0) return -1;

wchar_t* wbuf = (wchar_t*)malloc(len * sizeof(wchar_t));
if (!wbuf) return -1;

MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1, wbuf, len);

// 转换为系统默认编码
len = WideCharToMultiByte(acp_code, 0, wbuf, -1, acp_str, acp_size, NULL, NULL);
free(wbuf);

return len;

}

static void log_line(const char* tag, const char* msg) {
EnterCriticalSection(&g_cs);
char ts[64];
format_timestamp(ts, sizeof(ts));

// 构建完整的日志行
char full_msg[2048];
_snprintf(full_msg, sizeof(full_msg), "%s [%s] %s\n", ts, tag, msg);

// 输出到控制台:将UTF-8转换为系统默认编码
char console_msg[2048];
if (utf8_to_acp(full_msg, console_msg, sizeof(console_msg)) > 0) {
    fprintf(stdout, "%s", console_msg);
} else {
    // 转换失败时直接输出,可能会有乱码但至少能看到内容
    fprintf(stdout, "%s", full_msg);
}
fflush(stdout);

// 输出到文件:直接使用UTF-8编码
if (g_log) {
    fprintf(g_log, "%s", full_msg);
    fflush(g_log);
}
LeaveCriticalSection(&g_cs);

}

// 通用编码转换函数:将系统默认编码转换为UTF-8
static int acp_to_utf8(const char* acp_str, char* utf8_str, int utf8_size) {
// 获取系统默认代码页
UINT acp_code = GetACP();

// 转换为宽字符
int len = MultiByteToWideChar(acp_code, 0, acp_str, -1, NULL, 0);
if (len <= 0) return -1;

wchar_t* wbuf = (wchar_t*)malloc(len * sizeof(wchar_t));
if (!wbuf) return -1;

MultiByteToWideChar(acp_code, 0, acp_str, -1, wbuf, len);

// 转换为UTF-8
len = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, utf8_str, utf8_size, NULL, NULL);
free(wbuf);

return len;

}

// 原来的ping_worker函数已被线程池的thread_pool_worker替代

int main(void) {
g_mutex = CreateMutexA(NULL, TRUE, "PingLoopbackSingleInstance_Mutex");
if (!g_mutex) {
printf("Failed to create mutex\n");
return 1;
}
if (GetLastError() == ERROR_ALREADY_EXISTS) {
printf("Another instance is already running\n");
CloseHandle(g_mutex);
return 1;
}

InitializeCriticalSection(&g_cs);

// Get current exe file path
char exe_path[MAX_PATH] = {0};
GetModuleFileNameA(NULL, exe_path, MAX_PATH);

// Extract file name (without path)
char* exe_name = strrchr(exe_path, '\\');
if (!exe_name) {
    exe_name = exe_path;
} else {
    exe_name++;
}

// Create log file name with same name as exe, with .log extension
char log_path[MAX_PATH] = {0};
char* dot = strrchr(exe_name, '.');
if (dot) {
    // Copy file name up to dot
    size_t len = dot - exe_name;
    strncpy(log_path, exe_name, len);
    // Add .log extension
    strcat(log_path, ".log");
} else {
    // No extension case
    strcpy(log_path, exe_name);
    strcat(log_path, ".log");
}

// Open log file for writing in UTF-8
g_log = fopen(log_path, "a");
if (!g_log) {
    printf("Failed to open log file\n");
    DeleteCriticalSection(&g_cs);
    ReleaseMutex(g_mutex);
    CloseHandle(g_mutex);
    return 1;
}

// Check if file is empty, write UTF-8 BOM if needed
fseek(g_log, 0, SEEK_END);
if (ftell(g_log) == 0) {
    const char bom[3] = {0xEF, 0xBB, 0xBF};
    fwrite(bom, 1, sizeof(bom), g_log);
}
fseek(g_log, 0, SEEK_END);

{
    char startbuf[128];
    _snprintf(startbuf, sizeof(startbuf), "start pid=%lu", (unsigned long)GetCurrentProcessId());
    log_line("main", startbuf);
}

// 初始化线程池,队列大小为8
if (!init_thread_pool(8)) {
    log_line("main", "failed to initialize thread pool");
    DeleteCriticalSection(&g_cs);
    ReleaseMutex(g_mutex);
    CloseHandle(g_mutex);
    return 1;
}

// 创建工作线程
for (int i = 0; i < MAX_THREADS; i++) {
    g_thread_pool.threads[i] = CreateThread(NULL, 0, thread_pool_worker, (LPVOID)(intptr_t)(i + 1), 0, NULL);
    if (!g_thread_pool.threads[i]) {
        log_line("main", "failed to create thread");
    }
}

// 添加4个ping任务到线程池,使用不同的目标地址和ping次数
add_task_to_pool(1, "127.0.0.1", 2);  // ping本地回环地址2次
add_task_to_pool(2, "127.0.0.1", 2);  // ping本地回环地址2次
add_task_to_pool(3, "127.0.0.1", 2);  // ping本地回环地址2次
add_task_to_pool(4, "127.0.0.1", 2);  // ping本地回环地址2次

// 主线程保持运行,允许用户拖动控制台窗口
// 等待所有任务完成
BOOL all_tasks_done = FALSE;
while (!all_tasks_done) {
    // 检查已完成任务数是否等于总任务数
    WaitForSingleObject(g_thread_pool.completed_tasks_mutex, INFINITE);
    all_tasks_done = (g_thread_pool.completed_tasks >= g_thread_pool.total_tasks);
    ReleaseMutex(g_thread_pool.completed_tasks_mutex);
    
    if (!all_tasks_done) {
        Sleep(100);
    }
}

// 销毁线程池
destroy_thread_pool();

log_line("main", "all done");
fclose(g_log);
g_log = NULL;
DeleteCriticalSection(&g_cs);
ReleaseMutex(g_mutex);
CloseHandle(g_mutex);
return 0;

}

Expected behavior

N/A

Actual behavior

N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions