使用Windows信号量同步Windows文件映射

时间:2016-08-17 10:00:13

标签: c winapi

我想使用Windows信号量将同步添加到Windows文件映射。因此,一个进程创建文件映射,另一个进程(可能是多个其他进程)可以进入并访问共享的数据。任何人都可以提出如何做到这一点的建议。我做了以下事情:

在创建文件映射的过程中,我使用了CreateSemaphore并指定了名称。在另一个尝试访问数据的进程中,我使用OpenSemaphore获取创建的sempahore的句柄,然后我调用WaitForSingleObject,然后我打开此值,如果它WAIT_OBJECT0 ,我执行工作,最后在工作完成后调用ReleaseSemaphore。 我在C中使用JNI共享库执行此操作。

问题是它只是进入默认情况。还有什么我应该做的,或者我错过了什么?

我对Windows sems如何工作很新,我找不到具体的例子 他们如何在多个进程之间工作(没有线程)。如果有人能提出任何建议,我将不胜感激。

以下是一些代码:

创建文件映射

// create the semaphore here
semaphore = CreateSemaphore(
  NULL,
  10,
  10,
  SEMAPHORE_NAME
);

// some semaphore error checking
if (semaphore == NULL) {
  printf("Error occured creating semaphore %d\n", GetLastError());
  return -1;
}

//create mapping object
mappedFileHandle = CreateFileMapping (
  INVALID_HANDLE_VALUE,
  NULL,
  PAGE_READWRITE,
  0,
  BUFFER_SIZE,
  MEMORY_MAPPING_NAME
);

if (mappedFileHandle == NULL) {
  printf("Error creating a mapped file: %d", GetLastError());
  return -1;
}

// map view of a file into address space of a calling process
buffer = (LPCTSTR) MapViewOfFile (
  mappedFileHandle,
  FILE_MAP_ALL_ACCESS,
  0,
  0,
  BUFFER_SIZE
);

if (buffer == NULL) {
  printf("Could not map view");
  CloseHandle(mappedFileHandle);
  return -1;
}

CopyMemory(buffer, str, (_tcslen(str) * sizeof(TCHAR))); // problem!!
UnmapViewOfFile(buffer);
CloseHandle(mappedFileHandle);
//  CloseHandle(semaphore);

获取数据的流程代码

// try open the semahore
semaphore = OpenSemaphore (
  SEMAPHORE_ALL_ACCESS,
  NULL,
  SEMAPHORE_NAME
);

// some error checking
if (semaphore == NULL) {
  printf("Could not open semaphore %d\n", GetLastError());
  return -1;
}

waitResult = WaitForSingleObject(
  semaphore,
  -1 // block
);

// try to open the file mapping -- SHOULD BE DONE ATOMICALLY
// ======================================================================

switch (waitResult) {
  case WAIT_OBJECT_0:
          printf("Got in wait_result0");
          mappedFileHandle = OpenFileMapping (
            FILE_MAP_ALL_ACCESS,
            FALSE,
            MEMORY_MAPPING_NAME
          );

          if (mappedFileHandle == NULL) {
            printf("Could not open file mapping");
            return errorForJavaProgram;
          }

          // read data here, must be a critical region

          buffer = (LPTSTR) MapViewOfFile(
            mappedFileHandle,
            FILE_MAP_ALL_ACCESS,
            0,
            0,
            BUFFER_SIZE
          );

          if (buffer == NULL) {
            printf("Could not map view");
            CloseHandle(mappedFileHandle);
            return errorForJavaProgram;
          }

          message = (*env)->NewStringUTF(env, buffer);

          if (!ReleaseSemaphore(semaphore, 1, NULL)) {
            printf("An error occured releasing the semaphore: %d\n", GetLastError());
            return -1;
          }
    default:
      printf("Got to default \n");
} //switch

1 个答案:

答案 0 :(得分:1)

您的switch语句可能会失败。有关可在Stack Overflow上找到的众多讨论之一,请参阅Does case-switch work like this?

您的代码执行WAIT_OBJECT_0,然后继续执行default案例。您需要在break案例的最后添加returnWAIT_OBJECT_0