互斥锁的联用

本文展示了一个使用Windows API实现的多线程程序案例,通过Semaphore(信号量)、Mutex(互斥锁)和Event(事件)来协调多个线程间的资源访问与执行顺序。具体涉及如何创建线程、使用信号量限制同时访问资源的线程数量、利用互斥锁确保打印操作的原子性,以及借助事件对象更新资源使用的状态。

#include <windows.h>
#include <process.h>
#include <wchar.h>

void ReversePrintf(wchar_t *pContent);
unsigned __stdcall TestSemaphore(void *pParams);

struct AsynInfo
{
 wchar_t stringInfo[2][1024];
 int     nUseIndex[2];
 HANDLE  hSemaphore;
 HANDLE  hPrintMutex;
 HANDLE  hSetUseIndexEvent;
};

int _tmain(int argc, _TCHAR* argv[])
{
 AsynInfo testInfo;
 testInfo.hSemaphore = NULL;
 testInfo.nUseIndex[0] = 0;
 testInfo.nUseIndex[1] = 0;

 for(int i = 0; i < 2; i++)
 {
  memset(testInfo.stringInfo[i], 0 ,1024);
 }

 testInfo.hSemaphore =  CreateSemaphore(NULL, 0, 2, "JYYTest");
 testInfo.hPrintMutex = CreateMutex(NULL, FALSE, "testMutex");
 testInfo.hSetUseIndexEvent = CreateEvent(NULL, FALSE, TRUE, "JYYTEST3");
 
 HANDLE hTestThread[5] = {0};
 for(int i = 0; i < 5; i++)
 {
  hTestThread[i] = (HANDLE) _beginthreadex(NULL, 0, TestSemaphore, &testInfo, NULL, NULL);
 }

 ReleaseSemaphore(testInfo.hSemaphore, 2, NULL);

 WaitForMultipleObjects(5, hTestThread, TRUE, -1);
 for(int i = 0; i < 5; i++)
 {
  CloseHandle( hTestThread[i] );;
 }
 CloseHandle(testInfo.hPrintMutex);
 CloseHandle(testInfo.hSemaphore);

 printf("/r/n over /r/n");
 char cTest;
 scanf("%c", &cTest);

 return 0;
}

static nThreadCount = 0;

unsigned __stdcall TestSemaphore(void *pParams)
{
 if (NULL == pParams)
  return 0;
 
 AsynInfo *pAsynInfo = (AsynInfo *)pParams;
 int nThreadID = nThreadCount++;
 HANDLE resourceHandle[2];
 resourceHandle[0] = pAsynInfo->hSemaphore; 
 resourceHandle[1] = pAsynInfo->hSetUseIndexEvent;
 
 for (int i = 0; i < 3; i++)
 {
  WaitForMultipleObjects(2, resourceHandle, TRUE, -1);
  DWORD nFetchIndex = pAsynInfo->nUseIndex[0] == 0 ? 0: 1;
  pAsynInfo->nUseIndex[nFetchIndex] = 1;
  SetEvent(pAsynInfo->hSetUseIndexEvent);

  swprintf(pAsynInfo->stringInfo[nFetchIndex],
     L"the thread is %d, use buffer index is %d /r/n", nThreadID, nFetchIndex);
  WaitForSingleObject(pAsynInfo->hPrintMutex, -1);
  ReversePrintf(pAsynInfo->stringInfo[nFetchIndex]);
  ReleaseMutex(pAsynInfo->hPrintMutex);
  pAsynInfo->nUseIndex[nFetchIndex] = 0;
  ReleaseSemaphore(pAsynInfo->hSemaphore, 1, NULL);

  Sleep(1);
 }
 
 return 1;
}

void ReversePrintf(wchar_t *pContent)
{
 if (!pContent)
  return;
 
 wcsrev(pContent);
 wprintf(pContent);
 Sleep(500);
}

### 联芸1602芯片中实现IPC共享内存的配置方法 联芸科技(Maxio)1602是一种广泛应用于固态硬盘控制器领域的嵌入式芯片,通常基于ARM架构并运行实时操作系统(RTOS)或Linux系统。在该平台上实现IPC共享内存通信机制,主要依赖于底层操作系统的支持,特别是Linux环境下可使用POSIX共享内存或System V共享内存接口。 #### 使用POSIX共享内存进行配置 在Linux系统下,POSIX共享内存提供了一种简洁、现代的共享内存管理方式,适用于多进程间高效的数据交换[^1]。其核心函数包括 `shm_open` 和 `mmap`,可用于创建和映射共享内存区域。 ##### 示例代码(C语言) ```c #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main() { const char *name = "/my_shared_memory"; const size_t size = 4096; // 创建共享内存对象 int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); if (shm_fd == -1) { perror("shm_open"); return 1; } // 设置共享内存大小 if (ftruncate(shm_fd, size) == -1) { perror("ftruncate"); return 1; } // 映射共享内存到当前进程地址空间 void *ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); if (ptr == MAP_FAILED) { perror("mmap"); return 1; } // 写入数据 sprintf(ptr, "Hello from shared memory"); // 清理资源 munmap(ptr, size); close(shm_fd); return 0; } ``` 另一个进程可以使用相同的名称 `/my_shared_memory` 打开并访问该共享内存区域: ```c #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main() { const char *name = "/my_shared_memory"; const size_t size = 4096; int shm_fd = shm_open(name, O_RDONLY, 0666); if (shm_fd == -1) { perror("shm_open"); return 1; } void *ptr = mmap(0, size, PROT_READ, MAP_SHARED, shm_fd, 0); if (ptr == MAP_FAILED) { perror("mmap"); return 1; } printf("Read from shared memory: %s\n", (char *)ptr); munmap(ptr, size); close(shm_fd); return 0; } ``` #### 使用System V共享内存接口 System V IPC 提供了 `shmget`、`shmat` 等函数用于创建和访问共享内存段,适合对兼容性要求较高的场景。 ##### 示例代码(C语言) ```c #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <string.h> int main() { key_t key = ftok("shmfile", 65); int shmid = shmget(key, 1024, 0666 | IPC_CREAT); if (shmid == -1) { perror("shmget"); return 1; } char *str = (char *)shmat(shmid, NULL, 0); strcpy(str, "Data in System V shared memory"); printf("Written to shared memory\n"); shmdt(str); return 0; } ``` 读取端示例: ```c #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> int main() { key_t key = ftok("shmfile", 65); int shmid = shmget(key, 1024, 0666); if (shmid == -1) { perror("shmget"); return 1; } char *str = (char *)shmat(shmid, NULL, 0); printf("Read from shared memory: %s\n", str); shmdt(str); return 0; } ``` #### 同步机制建议 由于多个进程可能同时访问共享内存区域,需引入同步机制防止数据竞争问题。常用的方式包括互斥锁(mutex)、信号量(semaphore)等。 ##### 示例:使用POSIX信号量进行同步 ```c #include <semaphore.h> #include <fcntl.h> // 初始化信号量 sem_t *sem = sem_open("/my_semaphore", O_CREAT, 0644, 1); // 加锁 sem_wait(sem); // 访问共享内存 ... // 解锁 sem_post(sem); // 关闭信号量 sem_close(sem); ``` #### 注意事项 - **权限控制**:确保共享内存对象具有适当的访问权限,避免未授权进程访问敏感数据。 - **资源释放**:使用完毕后应及时调用 `shm_unlink` 或 `shmctl` 删除共享内存对象,避免资源泄漏。 - **命名唯一性**:共享内存名称应具有全局唯一性,以防止与其他程序冲突。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值