我正在尝试为复杂的计算进行多线程迭代,这需要与来自其他程序和交换数据(接收/发送)的其他线程流进行通信,如何让它们进行通信?以文件映射为例?这有用吗?
答案 0 :(得分:1)
假设您希望进程交替,那么您将需要两个信号量,每个进程将需要具有稍微不同的调用序列的代码:
流程A:
SemA = CreateAndInitializeSemaphore();
SemB = CreateAndInitializeSemaphore();
for (i = 0; i < Numpoints; i++)
{
WaitForSemaphore(SemA);
…code for process A…
SignalSemaphore(SemB);
}
除了信号量相反之外,B类似。
for (i = 0; i < Numpoints; i++)
{
WaitForSemaphore(SemB);
…code for process A…
SignalSemaphore(SemA);
}
请注意,创建SemA时,需要设置它以便A立即访问它。
所有信号量函数名称都需要映射到正确的实际系统调用。
答案 1 :(得分:1)
信号量和进程创建需要一些结构。
无警告定义是防止使用sscanf或sprintf的警告。 abCmdLine具有进程B(pb.exe)的名称和共享内存句柄的值。 (注意 - 句柄是指针类型)。
循环中有1/2秒的睡眠,所以你可以看到它是如何工作的。在这个例子中,两个循环同时运行。
更新 - 原始帖子已编辑。以前它特别提到了进程A和进程B,以及名为SemA,SemB的信号量和一个名为count的计数器。通过从原始帖子中删除这些名称,阅读此主题的人可能想知道为什么在这里的示例中使用这些名称。此示例中的其他名称遵循Microsoft / Windows匈牙利表示法样式。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <windows.h>
typedef struct SMEM_ /* shared memory offsets */
{
HANDLE SemA;
HANDLE SemB;
int count;
}SMEM, *PSMEM;
static HANDLE hMem; /* handle for shared memory */
static PSMEM psMem; /* ptr to shared memory */
/* bInheritHandle = TRUE */
static SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES),
NULL, TRUE};
static STARTUPINFO si = {sizeof(STARTUPINFO),
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/* hProcess = hThread = INVALID_HANDLE_VALUE */
static PROCESS_INFORMATION piB = {INVALID_HANDLE_VALUE,
INVALID_HANDLE_VALUE,
0, 0};
int main(int argc, char *argv[])
{
char abCmdLine[64];
hMem = CreateFileMapping(INVALID_HANDLE_VALUE,&sa,PAGE_READWRITE,0,
sizeof(SMEM),NULL);
if(hMem == INVALID_HANDLE_VALUE){
goto exit0;}
psMem = MapViewOfFile(hMem, FILE_MAP_WRITE, 0, 0, sizeof(SMEM));
if(psMem == NULL){
goto exit0;}
memset(psMem, 0, sizeof(SMEM));
/* process A waits before psMem->count++ */
psMem->SemA = CreateSemaphore(&sa,0,2,NULL);
if(psMem->SemA == INVALID_HANDLE_VALUE)
goto exit0;
/* process B waits for count to be updated */
psMem->SemB = CreateSemaphore(&sa,0,2,NULL);
if(psMem->SemB == INVALID_HANDLE_VALUE)
goto exit0;
/* create process B */
sprintf(abCmdLine, "pb.exe %p", hMem);
if(0 == CreateProcess(NULL, abCmdLine, NULL, NULL, TRUE,
CREATE_NEW_CONSOLE, NULL, NULL, &si, &piB))
goto exit0;
for(psMem->count = 0; psMem->count < 20; psMem->count++){
/* allow process B to use psMem->count */
ReleaseSemaphore(psMem->SemB, 1, NULL);
printf("%d\n", psMem->count);
Sleep(500);
/* wait before psMem->count++ */
WaitForSingleObject(psMem->SemA, INFINITE);
}
/* wait for process B to terminate */
WaitForSingleObject(piB.hProcess, INFINITE);
exit0:
if(piB.hThread != INVALID_HANDLE_VALUE)
CloseHandle(piB.hThread);
if(piB.hProcess != INVALID_HANDLE_VALUE)
CloseHandle(piB.hProcess);
if(psMem->SemB != INVALID_HANDLE_VALUE)
CloseHandle(psMem->SemB);
if(psMem->SemA != INVALID_HANDLE_VALUE)
CloseHandle(psMem->SemA);
if(hMem != INVALID_HANDLE_VALUE)
CloseHandle(hMem);
return(0);
}
进程B(pb.exe)
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <windows.h>
typedef struct SMEM_ /* shared memory offsets */
{
HANDLE SemA;
HANDLE SemB;
int count;
}SMEM, *PSMEM;
static HANDLE hMem; /* handle for shared memory */
static PSMEM psMem; /* ptr to shared memory */
int main(int argc, char *argv[])
{
int done = 0; /* done flag */
sscanf(argv[1], "%p", &hMem);
psMem = MapViewOfFile(hMem, FILE_MAP_WRITE, 0, 0, sizeof(SMEM));
if(psMem == NULL)
goto exit0;
while(!done){
/* wait for psMem->count to be updated */
WaitForSingleObject(psMem->SemB, INFINITE);
printf("%d\n", psMem->count);
Sleep(500);
done = psMem->count < 19 ? 0 : 1;
/* allow process A to update psMem->count */
ReleaseSemaphore(psMem->SemA, 1, NULL);
}
exit0:
return(0);
}