使用多线程获得连续的哔声

Posted

技术标签:

【中文标题】使用多线程获得连续的哔声【英文标题】:Using multithreading to get continuous beep sound 【发布时间】:2018-05-21 15:22:28 【问题描述】:

我正在尝试用 C++ 创建一个程序,在其中播放哔声,频率和持续时间由用户选择。

程序需要在播放哔声的同时继续运行。

我想我应该为此使用多线程,但我对此没有任何经验。

例如,这是一个简单的程序,但我在使用_beginthread时出错:

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <process.h>

using namespace std;

int freq = 0;
int sec = 0;
int mil = 0;

void beepTone(int freqq, int mill)

    Beep(freqq, mill);
    _endthread();


int main()

    cout << "Frequency?" << endl;
    cin >> freq;
    cout << "Duration?" << endl;
    cin >> sec;
    mil = 1000 * sec;
    _beginthread(beepTone(freq, mil), 0, NULL);
    cout << "Test Threading";
    return 0;

“void(*)(int freqq, int mill)”类型的参数与“_beginthread_proc_type”类型的参数不兼容

我认为这个测试程序的意义很明确。

我有可以运行的代码,但在这段代码中我无法选择自己的频率和持续时间:

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <process.h>

using namespace std;

void beepTone(void *arg)

    Beep(1000, 3000);
    _endthread();


int main()

    _beginthread(beepTone, 0, NULL);
    cout << "Test Threading";
    cin.get();
    return 0;

在继续程序的同时播放 1000Hz 3 秒。

谁能帮我告诉线程播放的频率和持续时间?

【问题讨论】:

你能用c++11吗?还是必须是c++98? 它不一定是 c++98 特定的,但老实说我不知道​​你说的这两者之间有什么区别,以及如何在它们之间进行更改.. 如果可以帮助你,我正在使用 Visual Studio 2017,我通过创建一个新的 C++ 项目来启动我的程序。所以我猜一切都在标准设置中。 vs2017 支持 C++11,因此您可以使用标准工具 &lt;thread&gt; 而不是像 _beginthread 这样的函数。 感谢您的快速响应,但我并没有完全明白应该如何在我的代码中实现 。就像我说的,我对线程完全陌生.. _beginthread 是一个 C 函数。它需要线程函数指针的特定签名。你违反了那份合同。 C++11 在 C++ 中引入了线程。 C++ 线程允许您将 any 函数作为线程函数传递。 Visual Studio 2017 支持 C++17,因此您可以利用 C++ threads。 【参考方案1】:

您的第一个示例无法编译,因为您实际上是在调用beepTone(),然后尝试将其void 返回值传递给_beginthread()start_address 参数,这将不起作用。您需要将beepTone() 本身传递给该参数,而不是其返回值。

您的第二个示例正确地将beepTone() 本身传递给_beginThread(),但没有将任何数据传递给beepTone()

现在,为了完成您想要的操作,_beginthread() 有一个 arglist 参数,您可以使用该参数将用户数据传递给您的线程函数。这就是您需要用来将哔声值发送到线程以便它可以将它们传递给Beep()

试试这样的:

#include "stdafx.h"
#include <Windows.h>
#include <process.h>
#include <iostream>

using namespace std;

struct beepParams

    int freq;
    int mil;
;

void __cdecl beepTone(void *arg)

    beepParams *params = static_cast<beepParams*>(arg);
    Beep(params->freq, params->mil);
    delete params;
    _endthread();


int main()

    int freq = 0, sec = 0, mil = 0;

    cout << "Frequency?" << endl;
    cin >> freq;
    cout << "Duration?" << endl;
    cin >> sec;
    mil = 1000 * sec;

    beepParams *params = new beepParams;
    params->freq = freq;
    params->mil = mil;

    if (_beginthread(&beepTone, 0, params) == -1)
        delete params;

    cout << "Test Threading";
    //...
    cin.get();

    return 0;

话虽如此,如果您使用的是 C++11 或更高版本,请考虑改用 std::thread

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <thread>

using namespace std;

struct beepParams

    int freq;
    int mil;
;

void beepTone(beepParams params)

    Beep(params.freq, params.mil);


int main()

    int freq = 0, sec = 0, mil = 0;

    cout << "Frequency?" << endl;
    cin >> freq;
    cout << "Duration?" << endl;
    cin >> sec;
    mil = 1000 * sec;

    beepParams params;
    params.freq = freq;
    params.mil = mil;

    thread t(beepTone, params);
    t.detach();

    cout << "Test Threading";
    //...
    cin.get();

    return 0;

【讨论】:

好吧。枪的儿子。我终于有机会坐下来回答这个问题,你比我早了大约 20 秒。 第一个示例缺少线程过程定义的调用约定。 @IInspectable _beginthread() 中线程过程的调用约定是__cdecl。大多数 C/C++ 编译器默认为__cdecl,当调用约定没有明确说明时。显然,如果您将编译器的默认值配置为 __cdecl 以外的其他值,那么您需要明确声明调用约定,以便它与预期的定义相匹配。

以上是关于使用多线程获得连续的哔声的主要内容,如果未能解决你的问题,请参考以下文章

C++ - 通过多线程同时播放多个哔声?

java 多线程-可重入锁

Java多线程与并发库高级应用-同步集合

[******] java多线程连续打印abc

java多线程编程之连续打印abc的几种解法

java多线程连续打印字母数字问题