首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在调用CreateFile打开串行端口"comX“时,如何设置有限的时间?

在调用CreateFile打开串行端口"comX“时,如何设置有限的时间?
EN

Stack Overflow用户
提问于 2017-03-17 02:23:50
回答 1查看 1.3K关注 0票数 1

我有一个蓝牙串口与硬件通信。如果硬件不通电,使用"CreateFile“将导致线程阻塞,并在5-6秒后造成”信号量超时时间已过期“的错误。是否可以通过设置超时时间来减少使用"CreateFile“的时间?谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-17 05:42:24

不幸的是,CreateFile只是同步的api,它不带任何超时参数(即使是低级别的ZwCreateFile也没有这个功能)。

在这种情况下所能做的最大的事情-移动调用CreateFile来分离线程,如果过了一段时间还没有完成-为这个线程调用CancelSynchronousIo。这可以帮上忙,但只有- I/O完成/取消准则

所有可能需要无限时间的IRPs (,包括Create)都必须被取消。

但是I/O子系统依赖于驱动程序,因此将取决于驱动程序处理串口的驱动程序,从而实现IRP_MJ_CREATE的取消。

代码语言:javascript
复制
struct OPEN_PACKET 
{
    PCWSTR lpFileName;
    HANDLE hFile;
    DWORD error;
    DWORD dwDesiredAccess;
    DWORD dwShareMode;
    DWORD dwCreationDisposition;
    DWORD dwFlagsAndAttributes;
};

DWORD WINAPI OpenComPort(OPEN_PACKET* op)
{
    HANDLE hFile = CreateFile(op->lpFileName, op->dwDesiredAccess, op->dwShareMode, 
        NULL, op->dwCreationDisposition,op->dwFlagsAndAttributes, NULL);

    op->error = hFile == INVALID_HANDLE_VALUE ? GetLastError() : NOERROR;
    op->hFile = hFile;

    return GetLastError();// for possible use GetExitCodeThread but use op->error better
}

void testCC(PCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes)
{
    OPEN_PACKET op = { lpFileName, INVALID_HANDLE_VALUE, ERROR_IO_PENDING, 
        dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes };

    ULONG ticks = GetTickCount();

    if (HANDLE hThread = CreateThread(NULL, PAGE_SIZE, (PTHREAD_START_ROUTINE)OpenComPort, &op, 0, NULL))
    {
        if (WaitForSingleObject(hThread, 1000) == WAIT_TIMEOUT)//1 sec for example
        {
            CancelSynchronousIo(hThread);
            WaitForSingleObject(hThread, INFINITE);
        }
        CloseHandle(hThread);
    }
    else
    {
        op.error = GetLastError();
    }

    ticks = GetTickCount() - ticks;

    WCHAR sz[256];
    if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, op.error, 0, sz, RTL_NUMBER_OF(sz), NULL)) *sz = 0;
    DbgPrint("[%u ms] hFile=%p err=%u %S\n", ticks, op.hFile, op.error, sz);

    if (op.hFile != INVALID_HANDLE_VALUE)
    {
        CloseHandle(op.hFile);
    }
}

void ep()
{
    testCC(L"\\\\server\\share\\1.txt", FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_SHARE_VALID_FLAGS, OPEN_EXISTING, 0);
    testCC(L"\\\\?\\globalroot\\systemroot\\notepad.exe", FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_SHARE_VALID_FLAGS, OPEN_EXISTING, 0);
    testCC(L"\\\\?\\globalroot\\systemroot\\notepad.exe", FILE_GENERIC_READ, FILE_SHARE_VALID_FLAGS, OPEN_EXISTING, 0);
}

我得到了下一个结果:

代码语言:javascript
复制
[1000 ms] hFile=FFFFFFFFFFFFFFFF err=995 The I/O operation has been aborted because of either a thread exit or an application request.

[0 ms] hFile=FFFFFFFFFFFFFFFF err=5 Access is denied.

[0 ms] hFile=0000000000000154 err=0 The operation completed successfully.
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42848131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档