如何使用Windows API直接将进程"assign"到信号量?
How to directly "assign" a process to a semaphore using windows API?
我使用来自Microsoft的以下代码作为模板:
#include <windows.h>
#include <stdio.h>
#define MAX_SEM_COUNT 10
#define THREADCOUNT 12
HANDLE ghSemaphore;
DWORD WINAPI ThreadProc( LPVOID );
int main( void )
{
HANDLE aThread[THREADCOUNT];
DWORD ThreadID;
int i;
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
ghSemaphore = CreateSemaphore(
NULL, // default security attributes
MAX_SEM_COUNT, // initial count
MAX_SEM_COUNT, // maximum count
NULL); // unnamed semaphore
if (ghSemaphore == NULL)
{
printf("CreateSemaphore error: %dn", GetLastError());
return 1;
}
// Create worker threads
for( i=0; i < THREADCOUNT; i++ )
{
aThread[i] = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ThreadProc,
NULL, // no thread function arguments
0, // default creation flags
&ThreadID); // receive thread identifier
if( aThread[i] == NULL )
{
printf("CreateThread error: %dn", GetLastError());
return 1;
}
}
// Wait for all threads to terminate
WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);
// Close thread and semaphore handles
for( i=0; i < THREADCOUNT; i++ )
CloseHandle(aThread[i]);
CloseHandle(ghSemaphore);
return 0;
}
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
// lpParam not used in this example
UNREFERENCED_PARAMETER(lpParam);
DWORD dwWaitResult;
BOOL bContinue=TRUE;
while(bContinue)
{
// Try to enter the semaphore gate.
dwWaitResult = WaitForSingleObject(
ghSemaphore, // handle to semaphore
0L); // zero-second time-out interval
switch (dwWaitResult)
{
// The semaphore object was signaled.
case WAIT_OBJECT_0:
// TODO: Perform task
printf("Thread %d: wait succeededn", GetCurrentThreadId());
bContinue=FALSE;
// Simulate thread spending time on task
Sleep(5);
// Release the semaphore when task is finished
if (!ReleaseSemaphore(
ghSemaphore, // handle to semaphore
1, // increase count by one
NULL) ) // not interested in previous count
{
printf("ReleaseSemaphore error: %dn", GetLastError());
}
break;
// The semaphore was nonsignaled, so a time-out occurred.
case WAIT_TIMEOUT:
printf("Thread %d: wait timed outn", GetCurrentThreadId());
break;
}
}
return TRUE;
}
我想对其进行调整,使其不是由线程来决定信号量如何填充,而是由进程来完成,这意味着如果有进程在运行和/或它们的任何一个habdles没有关闭,信号量就会填充,事实上,我已经通过用这个新函数改变线程函数的工作方式来完成了这一点。
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
// lpParam not used in this example
UNREFERENCED_PARAMETER(lpParam);
DWORD dwWaitResult;
BOOL bContinue=TRUE;
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
while(bContinue)
{
// Try to enter the semaphore gate.
dwWaitResult = WaitForSingleObject(
ghSemaphore, // handle to semaphore
0L); // zero-second time-out interval
CreateProcess("arbol.exe",NULL,NULL,NULL,0,0,NULL,NULL,&si,&pi);
WaitForSingleObject(pi.hProcess,INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
switch (dwWaitResult)
{
// The semaphore object was signaled.
case WAIT_OBJECT_0:
// TODO: Perform task
printf("Thread %d: wait succeededn", GetCurrentThreadId());
bContinue=FALSE;
// Simulate thread spending time on task
Sleep(5);
// Release the semaphore when task is finished
if (!ReleaseSemaphore(
ghSemaphore, // handle to semaphore
1, // increase count by one
NULL) ) // not interested in previous count
{
printf("ReleaseSemaphore error: %dn", GetLastError());
}
break;
// The semaphore was nonsignaled, so a time-out occurred.
case WAIT_TIMEOUT:
printf("Thread %d: wait timed outn", GetCurrentThreadId());
break;
}
}
return TRUE;
}
因此,尽管决定信号量填充的是线程,但在实际意义上,它是由进程句柄的完全执行和关闭来决定的。
但这看起来是解决这个问题的一种蹩脚的方法,我敢打赌,如果这些过程需要额外的东西,那么这样做可能会在未来产生问题。
我如何创建一个信号量,以便真正决定信号量填充的是进程?澄清一下,这将是一个可能的解决方案,我认为无论如何都不可能。
让我们考虑一下,您可以通过以下方式创建流程:
aThread[i] = CreateProcess(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ThreadProc,
NULL, // no thread function arguments
0, // default creation flags
&ThreadID); // receive thread identifier
那么LPTHREAD_START_ROUTINE在其工作中是等效的,但对于进程来说是等效的。
信号应该支持Windows API中的进程间同步,但我找不到任何专门使用进程的示例,也不知道如何实现。
你知道如何实现我想要的吗?
谨致问候。
您想要一个命名的信号量。其中,每个进程通过创建具有相同名称的信号量来共享信号量。
创建一个命名信号量。和以前一样,但最后一个参数会得到一个传递给它的字符串:
HANDLE hSemaphore = CreateSemaphore(NULL,
MAX_SEM_COUNT,
MAX_SEM_COUNT,
L"TheSemaphoreForMyApp");
启动后,子进程可以连接到同一个信号量,并通过使用OpenSemaphore获得它的句柄。
HANDLE hSemaphore = OpenSemaphore(EVENT_ALL_ACCESS,
FALSE,
L"TheSemaphoreForMyApp");
您不必将字符串硬编码为信号量名称。父进程每次都可以创建一个唯一的名称,然后将该名称(例如命令行参数)传递给子进程。这将允许具有子进程的程序的多个实例进行协作。
相关文章:
- 删除旧的信号量系统V
- 父进程和子进程之间的 POSIX 信号量
- 访问共享内存而不使用易失性、std::atomic、信号量、互斥锁和自旋锁
- 多线程.如果我使用信号量,我可以在开始时创建很多线程还是应该只有几个线程?
- C/C++ - 用于按顺序打印数字的 sem_t 类型的单个信号量
- 单车道桥 使用信号量进行同步
- 用于 64 位/32 位 IPC 的 POSIX 信号量的替代方案?
- 这个餐饮哲学家问题(dpp)的解决方案是如何工作的?互斥体和信号量
- 发布信号量返回错误 6(无效句柄)
- 在 C Linux 中使用三个线程使用信号量同步按顺序打印 3 4 5 50 次
- 在使用 pthread 和信号量实现生产者-消费者问题时需要帮助
- 如何让一个线程继续,而另一个线程正在等待C++中的信号量
- 实现信号量
- 计算信号量还是互斥体?
- POSIX 信号量在高争用/负载下不起作用
- C++:提升:托管共享内存是否需要信号量锁
- 信号量的问题
- 如何使用Windows API直接将进程"assign"到信号量?
- 从主线程C++更新信号量
- 生产者 - 消费者生产商创建2个元素POSIX信号量