gpt4 book ai didi

c++ - c++并发调用时如何保证CreateProcess只创建一个进程?

转载 作者:可可西里 更新时间:2023-11-01 09:56:52 25 4
gpt4 key购买 nike

引自here :

BOOL WINAPI CreateProcess(
__in_opt LPCTSTR lpApplicationName,
__inout_opt LPTSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCTSTR lpCurrentDirectory,
__in LPSTARTUPINFO lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);

我有两个创建完全相同进程的独立程序,我如何确保如果其中一个已经创建了进程,另一个不会创建两次?

最佳答案

最简单的方法是在程序启动后创建一个命名对象。例如CreateEvent , CreateMutex等等。要验证应用程序的存在,您可以使用 OpenEvent , OpenMutex在创建对象之前依此类推。您可以选择(如果需要)带有“Global\”前缀的对象名称(请参阅 http://msdn.microsoft.com/en-us/library/aa382954.aspx ),以便所有终端服务器 session 仅允许一个进程。

已更新:因为我怎么能看到对我的建议有不同的意见我尝试更准确地解释它并添加相应的测试示例。

主要思想是启动的应用程序创建任何命名对象是尚未存在的同名对象。这只保留Kernel Object Namespaces中的名称.不需要实际使用该对象。与在磁盘上创建文件相比,这种方式的优势在于命名对象是临时并且由应用程序拥有。因此,如果应用程序结束、被终止或以任何其他方式终止(例如,由于未处理的异常),操作系统将自动删除命名对象。在下面的示例中,我根本不使用 CloseHandle。您如何测试应用程序才能成功确定它是否作为第一个实例运行。

#include <windows.h>
//#include <Sddl.h>

LPCTSTR g_pszEventName = TEXT("MyTestEvent"); // TEXT("Global\\MyTestEvent")

void DisplayFirstInstanceStartedMessage()
{
TCHAR szText[1024];
wsprintf (szText,
TEXT("The first instance are started.\nThe event with the name \"%s\" is created."),
g_pszEventName);

MessageBox (NULL,
szText,
TEXT("CreateEventTest"), MB_OK);
}

void DisplayAlreadyRunningMessage ()
{
TCHAR szText[1024];
wsprintf (szText,
TEXT("The first instance of the aplication is already running.\nThe event with the name \"%s\" already exist."),
g_pszEventName);

MessageBox (NULL,
szText,
TEXT("CreateEventTest"), MB_ICONWARNING | MB_OK);
}

void DisplayErrorMessage (DWORD dwErrorCode)
{
if (dwErrorCode == ERROR_ALREADY_EXISTS)
DisplayAlreadyRunningMessage();
else {
LPTSTR pErrorString;
if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | // Always search in system message table !!!
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
0, NULL, // source of message definition
dwErrorCode, // message ID
// 0, // language ID
// GetUserDefaultLangID(), // language ID
// GetSystemDefaultLangID(),
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&pErrorString, // pointer for buffer to allocate
0, // min number of chars to allocate
NULL)) {
MessageBox (NULL, pErrorString, TEXT("CreateEventTest"), MB_OK);
LocalFree (pErrorString);
}
else {
TCHAR szText[1024];
wsprintf (szText, TEXT("Error %d in the CreateEvent(..., \"%s\")"), dwErrorCode, g_pszEventName);
MessageBox (NULL, szText, TEXT("CreateEventTest"), MB_OK);
}
}
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
//SECURITY_ATTRIBUTES sa;
//BOOL bSuccess;
HANDLE hEvent = OpenEvent (EVENT_MODIFY_STATE, FALSE, g_pszEventName);// EVENT_ALL_ACCESS
if (hEvent == NULL) {
DWORD dwErrorCode = GetLastError();
if (dwErrorCode != ERROR_FILE_NOT_FOUND) {
DisplayErrorMessage(dwErrorCode);
return 1;
}
}
else {
DisplayAlreadyRunningMessage();
return 0;
}

//sa.bInheritHandle = FALSE;
//sa.nLength = sizeof(SECURITY_ATTRIBUTES);
//bSuccess = ConvertStringSecurityDescriptorToSecurityDescriptor (
// TEXT("D:(A;OICI;GA;;;WD)"), // Allow full control
// SDDL_REVISION_1,
// &sa.lpSecurityDescriptor,
// NULL);
hEvent = CreateEvent (NULL, // &sa
TRUE, FALSE, g_pszEventName);
//sa.lpSecurityDescriptor = LocalFree (sa.lpSecurityDescriptor);
if (hEvent == NULL) {
DWORD dwErrorCode = GetLastError();
DisplayErrorMessage(dwErrorCode);
return 1;
}
else
DisplayFirstInstanceStartedMessage();

return 0;
UNREFERENCED_PARAMETER (hInstance);
UNREFERENCED_PARAMETER (hPrevInstance);
UNREFERENCED_PARAMETER (lpCmdLine);
UNREFERENCED_PARAMETER (nShowCmd);
}

如果希望支持来自同一桌面或来自不同桌面的不同用户只能启动程序的一个实例,可以取消注释某些部分的注释代码或替换名称 MyTestEvent Global\MyTestEvent 的事件。

我希望在这个例子之后我的立场会很明确。在此类事件使用中,不需要调用 WaitForSingleObject()

关于c++ - c++并发调用时如何保证CreateProcess只创建一个进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3540679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com