谷歌面试题 多线程的同步与互斥操作
来源:互联网 发布:淘宝阿里旺旺在哪里 编辑:程序博客网 时间:2024/05/22 09:45
题目来源:秒杀多线程第一篇 多线程笔试面试题汇总
/********************************/
第五题(Google面试题)
有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推………现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:
A:1 2 3 4 1 2….
B:2 3 4 1 2 3….
C:3 4 1 2 3 4….
D:4 1 2 3 4 1….
请设计程序。
/********************************/
以下是本人作答部分。
#include "stdio.h"#include <WINDOWS.H>#define BUF_LEN 50#define THREAD_NUM 4#define EVENT_NUM 4char g_ABuf[BUF_LEN] = {0}; //模拟文件 A 下同int g_ABufTail = 0;char g_BBuf[BUF_LEN] = {0};int g_BBufTail = 0;char g_CBuf[BUF_LEN] = {0};int g_CBufTail = 0;char g_DBuf[BUF_LEN] = {0};int g_DBufTail = 0;/** 0 [0][1][2][3] 第0组用于同步对文件A的写操作,依次类推* 1 [0][1][2][3]* 2 [0][1][2][3]* 3 [0][1][2][3]*/HANDLE g_EventHandle[EVENT_NUM][EVENT_NUM] = {INVALID_HANDLE_VALUE}; //同步四个文件写入操作DWORD g_dwThreadID[THREAD_NUM] = {0};//线程IDHANDLE g_ExitThreadHandle = INVALID_HANDLE_VALUE; //等待退出线程HANDLE g_ThreadExitHandle[THREAD_NUM] = {INVALID_HANDLE_VALUE};//线程退出,通知主线程DWORD WINAPI ThreadFunc(LPVOID lparam);void WriteABuffer(DWORD dwTmp);//文件A写操作 下同void WriteBBuffer(DWORD dwTmp);void WriteCBuffer(DWORD dwTmp);void WriteDBuffer(DWORD dwTmp);CRITICAL_SECTION g_Critical;void WriteABuffer(DWORD dwTmp){ //使用临界区对文件A的访问加锁,使多个线程可以互斥访问 下同 EnterCriticalSection(&g_Critical); if (g_ABufTail >= BUF_LEN) { LeaveCriticalSection(&g_Critical); return ; } g_ABuf[g_ABufTail++] = (char)dwTmp + (char)0x31; Sleep(10); LeaveCriticalSection(&g_Critical);}void WriteBBuffer(DWORD dwTmp){ EnterCriticalSection(&g_Critical); if (g_BBufTail >= BUF_LEN) { LeaveCriticalSection(&g_Critical); return ; } g_BBuf[g_BBufTail++] = (char)dwTmp + (char)0x31; Sleep(20); LeaveCriticalSection(&g_Critical);}void WriteCBuffer(DWORD dwTmp){ EnterCriticalSection(&g_Critical); if (g_CBufTail >= BUF_LEN) { LeaveCriticalSection(&g_Critical); return ; } g_CBuf[g_CBufTail++] = (char)dwTmp + (char)0x31; Sleep(5); LeaveCriticalSection(&g_Critical);}void WriteDBuffer(DWORD dwTmp){ EnterCriticalSection(&g_Critical); if (g_DBufTail >= BUF_LEN) { LeaveCriticalSection(&g_Critical); return ; } g_DBuf[g_DBufTail++] = (char)dwTmp + (char)0x31; Sleep(15); LeaveCriticalSection(&g_Critical);}DWORD WINAPI ThreadFunc( LPVOID lparam ){ DWORD ldw_ThreadID = (DWORD)lparam; DWORD dwRt = 0; DWORD dwii = 0; while(1) { dwRt = WaitForSingleObject(g_ExitThreadHandle,0); //等待主线程通知何时退出 if (WAIT_OBJECT_0 == dwRt) { break; } dwii = (THREAD_NUM + ldw_ThreadID - 1)%THREAD_NUM; //计算需等待的前一个事件对象的下标 dwRt = WaitForSingleObject(g_EventHandle[0][dwii],0);//对于文件A,本线程需等待前一个线程的信号 if (WAIT_OBJECT_0 == dwRt) { WriteABuffer(ldw_ThreadID); SetEvent(g_EventHandle[0][ldw_ThreadID]);//将本线程事件对象设置为有信号状态,以此通知下一个线程对文件A写操作 } dwRt = WaitForSingleObject(g_EventHandle[1][dwii],0); if (WAIT_OBJECT_0 == dwRt) { WriteBBuffer(ldw_ThreadID); SetEvent(g_EventHandle[1][ldw_ThreadID]); } dwRt = WaitForSingleObject(g_EventHandle[2][dwii],0); if (WAIT_OBJECT_0 == dwRt) { WriteCBuffer(ldw_ThreadID); SetEvent(g_EventHandle[2][ldw_ThreadID]); } dwRt = WaitForSingleObject(g_EventHandle[3][dwii],0); if (WAIT_OBJECT_0 == dwRt) { WriteDBuffer(ldw_ThreadID); SetEvent(g_EventHandle[3][ldw_ThreadID]); } } SetEvent(g_ThreadExitHandle[ldw_ThreadID]); //通知主线程,本线程已退出 return 0;}int main(){ int ii = 0,jj = 0,kk = 0; //初始化临界区 InitializeCriticalSection(&g_Critical); //创建各部分事件对象及线程 g_ExitThreadHandle = CreateEvent(NULL,TRUE,FALSE,NULL); for (jj = 0; jj < EVENT_NUM;jj++) { for(kk = 0; kk < EVENT_NUM;kk++) g_EventHandle[jj][kk] = CreateEvent(NULL,FALSE,FALSE,NULL); } //按需设置事件对象为信号状态 SetEvent(g_EventHandle[0][3]); SetEvent(g_EventHandle[1][0]); SetEvent(g_EventHandle[2][1]); SetEvent(g_EventHandle[3][2]); HANDLE lh_ThreadHandle = INVALID_HANDLE_VALUE; for(ii = 0 ; ii < THREAD_NUM;ii++) { lh_ThreadHandle = CreateThread(NULL,0,ThreadFunc,(LPVOID)ii,0,&g_dwThreadID[ii]); if (NULL != lh_ThreadHandle) { //释放主线程对内核对象的引用计数 CloseHandle(lh_ThreadHandle); } else return -1; g_ThreadExitHandle[ii] = CreateEvent(NULL,FALSE,FALSE,NULL); } printf("按下回车查看运行结果"); while(getchar() != '\n');//等待按下回车,退出程序 SetEvent(g_ExitThreadHandle); //wait thread exit and delete critical section DWORD dwrt = WaitForMultipleObjects(THREAD_NUM,g_ThreadExitHandle,TRUE,INFINITE); DeleteCriticalSection(&g_Critical); //清理内核对象的引用计数 CloseHandle(g_ExitThreadHandle); g_ExitThreadHandle = INVALID_HANDLE_VALUE; for (jj = 0; jj < EVENT_NUM;jj++) { for(kk = 0; kk < EVENT_NUM;kk++) { CloseHandle(g_EventHandle[jj][kk]); g_EventHandle[jj][kk] = INVALID_HANDLE_VALUE; } } for(ii = 0 ; ii < THREAD_NUM;ii++) { CloseHandle(g_ThreadExitHandle[ii]); g_ThreadExitHandle[ii] = INVALID_HANDLE_VALUE; } //输出结果 for (ii = 0;ii < g_ABufTail;ii++) { putchar(g_ABuf[ii]); } putchar('\n'); for (ii = 0;ii < g_BBufTail;ii++) { putchar(g_BBuf[ii]); } putchar('\n'); for (ii = 0;ii < g_CBufTail;ii++) { putchar(g_CBuf[ii]); } putchar('\n'); for (ii = 0;ii < g_DBufTail;ii++) { putchar(g_DBuf[ii]); } putchar('\n'); printf("按下回车退出"); while(getchar() != '\n'); return 0;}
0 0
- 谷歌面试题 多线程的同步与互斥操作
- Windows多线程的同步与互斥
- linux多线程的互斥与同步
- 多线程的互斥与同步
- 多线程的互斥与同步
- Windows多线程的同步与互斥
- 多线程的同步与互斥
- Linux多线程的同步与互斥
- Linux多线程的同步与互斥
- Linux的多线程--同步与互斥
- 6.多线程的同步与互斥
- 多线程同步与互斥
- 多线程同步与互斥
- 多线程同步与互斥
- 多线程同步与互斥
- 多线程同步与互斥
- 多线程互斥与同步
- 多线程同步与互斥
- ajax返回json数据
- bash使用
- react-native如何搭建开发环境搭建上手教程(转)
- 详解C中volatile关键字
- 如何限制对象只能建立在堆上或者栈上
- 谷歌面试题 多线程的同步与互斥操作
- linux下svn客户端安装及使用
- cygwin自动安装工具
- catalan数 + 二叉树 —— POJ 1095
- Collection探究之HashMap
- 【LeetCode从零单刷】Set Matrix Zeroes
- 设计模式之--依赖倒置原则
- iOS 中利用 Masonry 进行代码适配的基本方法
- sqlite3的安装和使用