面试题-多线程编程

简介: 题目: 四个线程 t1,t2,t3,t4,向 4 个文件中写入数据, t1 只能写入 1, t2 只能写入 2, t3 只能写入 3, t4 只能写入 4,对 4 个文件 A, B, C, D 写入如下内容A:123412341234.....B:234123412341....C:341234123412....D:412341234123....   怎么实现同步可以让线程并行工作? 用windows c++实现. // 222_thread.cpp : 定义控制台应用程序的入口点。

题目:

四个线程 t1,t2,t3,t4,向 4 个文件中写入数据, t1 只能写入 1, t2 只能写入 2, t3 只能写
入 3, t4 只能写入 4,对 4 个文件 A, B, C, D 写入如下内容
A:123412341234.....
B:234123412341....
C:341234123412....
D:412341234123....

 

怎么实现同步可以让线程并行工作?

用windows c++实现.

// 222_thread.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <thread>
#include <iostream>
using namespace std;



HANDLE ghMutex;
HANDLE handles[4][4];
int idxx = 1;

void threadA()
{
    int idx = 0;
    do
    {
        DWORD res = WaitForMultipleObjects(4, handles[0], false, INFINITE);

        WaitForSingleObject(ghMutex, INFINITE);
        switch (res)
        {
        case WAIT_OBJECT_0:
            cout << "A"  ;
            SetEvent(handles[1][0]);
            break;
        case WAIT_OBJECT_0+1:
            cout << "B";
            SetEvent(handles[1][1]);
            break;
        case WAIT_OBJECT_0+2:
            cout << "C";
            SetEvent(handles[1][2]);
            break;
        case WAIT_OBJECT_0+3:
            cout << "D";
            SetEvent(handles[1][3]);
            break;
        }
        cout << 1;
        idxx++;
        ReleaseMutex(ghMutex);
    } while (idxx < 50);
    
}

void threadB()
{    
    int idx = 0;
    do
    {
        DWORD res = WaitForMultipleObjects(4, handles[1], false, INFINITE);
        WaitForSingleObject(ghMutex, INFINITE);
        switch (res)
        {
        case WAIT_OBJECT_0:
            cout << "A";
            SetEvent(handles[2][0]);
            break;
        case WAIT_OBJECT_0 + 1:
            cout << "B";
            SetEvent(handles[2][1]);
            break;
        case WAIT_OBJECT_0 + 2:
            cout << "C";
            SetEvent(handles[2][2]);
            break;
        case WAIT_OBJECT_0 + 3:
            cout << "D";
            SetEvent(handles[2][3]);
            break;
        }
        cout << 2;
        idxx++;
        ReleaseMutex(ghMutex);
    } while (idxx < 50);
}
void threadC()
{
    int idx = 0;
    do
    {
        DWORD res = WaitForMultipleObjects(4, handles[2], false, INFINITE);
        WaitForSingleObject(ghMutex, INFINITE);
        switch (res)
        {
        case WAIT_OBJECT_0:
            cout << "A";
            SetEvent(handles[3][0]);
            break;
        case WAIT_OBJECT_0 + 1:
            cout << "B";
            SetEvent(handles[3][1]);
            break;
        case WAIT_OBJECT_0 + 2:
            cout << "C";
            SetEvent(handles[3][2]);
            break;
        case WAIT_OBJECT_0 + 3:
            cout << "D";
            SetEvent(handles[3][3]);
            break;
        }
        cout << 3;
        idxx++;
        ReleaseMutex(ghMutex);
    } while (idxx < 50);
}
void threadD()
{
    int idx = 0;
    do
    {
        DWORD res = WaitForMultipleObjects(4, handles[3], false, INFINITE);
        WaitForSingleObject(ghMutex, INFINITE);
        switch (res)
        {
        case WAIT_OBJECT_0:
            cout << "A";
            SetEvent(handles[0][0]);
            break;
        case WAIT_OBJECT_0 + 1:
            cout << "B";
            SetEvent(handles[0][1]);
            break;
        case WAIT_OBJECT_0 + 2:
            cout << "C";
            SetEvent(handles[0][2]);
            break;
        case WAIT_OBJECT_0 + 3:
            cout << "D";
            SetEvent(handles[0][3]);
            break;
        }
        cout << 4;
        idxx++;
        ReleaseMutex(ghMutex);
    } while (idxx < 50);
}

void WriteA()
{
    SetEvent(handles[0][0]);
}
void WriteB()
{
    SetEvent(handles[1][1]);
}
void WriteC()
{
    SetEvent(handles[2][2]);
}
void WriteD()
{
    SetEvent(handles[3][3]);
}

int _tmain(int argc, _TCHAR* argv[])
{
    /*            file A      file B        file C       file D
      thread 1 handle[0][0] handle[0][1] handle[0][2] handle[0][3] 
      thread 2 handle[1][0] handle[1][1] handle[1][2] handle[1][3]
      thread 3 handle[2][0] handle[2][1] handle[2][2] handle[2][3]
      thread 4 handle[3][0] handle[3][1] handle[3][2] handle[3][3]
    */

    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            handles[i][j] = CreateEvent(NULL, false, false, NULL);
        }
    }

    DWORD threadID;
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadA, NULL, 0, &threadID);
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadB, NULL, 0, &threadID);
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadC, NULL, 0, &threadID);
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadD, NULL, 0, &threadID);

    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WriteA, NULL, 0, &threadID);
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WriteB, NULL, 0, &threadID);
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WriteC, NULL, 0, &threadID);
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WriteD, NULL, 0, &threadID);

    ghMutex = CreateMutex(
        NULL,              // default security attributes
        FALSE,             // initially not owned
        NULL);             // unnamed mutex

    if (ghMutex == NULL)
    {
        printf("CreateMutex error: %d\n", GetLastError());
        return 1;
    }

    Sleep(60000);
    return 0;
}

 



 


作者: HarlanC

博客地址: http://www.cnblogs.com/harlanc/
个人博客: http://www.harlancn.me/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接

如果觉的博主写的可以,收到您的赞会是很大的动力,如果您觉的不好,您可以投反对票,但麻烦您留言写下问题在哪里,这样才能共同进步。谢谢!

目录
相关文章
|
5月前
|
机器学习/深度学习 消息中间件 存储
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
189 0
|
9月前
|
监控 Kubernetes Java
阿里面试:5000qps访问一个500ms的接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?
本文由40岁老架构师尼恩撰写,针对一线互联网企业的高频面试题“如何确定系统的最佳线程数”进行系统化梳理。文章详细介绍了线程池设计的三个核心步骤:理论预估、压测验证和监控调整,并结合实际案例(5000qps、500ms响应时间、4核8G机器)给出具体参数设置建议。此外,还提供了《尼恩Java面试宝典PDF》等资源,帮助读者提升技术能力,顺利通过大厂面试。关注【技术自由圈】公众号,回复“领电子书”获取更多学习资料。
|
7月前
|
人工智能 监控 JavaScript
Crack Coder:在线面试“AI外挂”!编程问题秒出答案,完全绕过屏幕监控,连录屏都抓不到痕迹!
Crack Coder 是一款开源的隐形 AI 辅助工具,专为技术面试设计,支持多种编程语言,提供实时编程问题解决方案,帮助面试者高效解决问题。
248 14
|
9月前
|
安全 Java 程序员
面试必看:如何设计一个可以优雅停止的线程?
嘿,大家好!我是小米。今天分享一篇关于“如何停止一个正在运行的线程”的面试干货。通过一次Java面试经历,我明白了停止线程不仅仅是技术问题,更是设计问题。Thread.stop()已被弃用,推荐使用Thread.interrupt()、标志位或ExecutorService来优雅地停止线程,避免资源泄漏和数据不一致。希望这篇文章能帮助你更好地理解Java多线程机制,面试顺利! 我是小米,喜欢分享技术的29岁程序员。欢迎关注我的微信公众号“软件求生”,获取更多技术干货!
217 53
|
8月前
|
数据采集 Java Linux
面试大神教你:如何巧妙回答线程优先级这个经典考题?
大家好,我是小米。本文通过故事讲解Java面试中常见的线程优先级问题。小明和小华的故事帮助理解线程优先级:高优先级线程更可能被调度执行,但并非越高越好。实际开发需权衡业务需求,合理设置优先级。掌握线程优先级不仅能写出高效代码,还能在面试中脱颖而出。最后,小张因深入分析成功拿下Offer。希望这篇文章能助你在面试中游刃有余!
124 4
面试大神教你:如何巧妙回答线程优先级这个经典考题?
|
8月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
132 26
|
8月前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
479 14
|
8月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
136 17
|
8月前
|
安全 Java 程序员
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
133 13
|
8月前
|
缓存 安全 Java
面试中的难题:线程异步执行后如何共享数据?
本文通过一个面试故事,详细讲解了Java中线程内部开启异步操作后如何安全地共享数据。介绍了异步操作的基本概念及常见实现方式(如CompletableFuture、ExecutorService),并重点探讨了volatile关键字、CountDownLatch和CompletableFuture等工具在线程间数据共享中的应用,帮助读者理解线程安全和内存可见性问题。通过这些方法,可以有效解决多线程环境下的数据共享挑战,提升编程效率和代码健壮性。
244 6