多线程以减少CPU时间

时间:2015-05-17 20:13:35

标签: synchronization

我正在尝试为复杂的计算进行多线程迭代,这需要与来自其他程序和交换数据(接收/发送)的其他线程流进行通信,如何让它们进行通信?以文件映射为例?这有用吗?

2 个答案:

答案 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);
}