【问题标题】:_beginthread and WaitForSingleObject_beginthread 和 WaitForSingleObject
【发布时间】:2012-05-04 20:15:06
【问题描述】:

我正在实现一个启动 4 个线程的程序。

功能有:

void* SOURCE_in(struct SOURCE_1*);
void* SOURCE_out(struct SOURCE*);
void* SINK_out(struct SINK_1*);
void* SINK_in(struct SINK*);

这些函数允许在 4 个块之间进行通信。 块 1 与块 2 通信。 块 2 与第三块共享信息。 Block 3 与 Block 4 进行信息交流。

我的问题在 main.c 中

int main(int argc, char** argv){

    extern int p, e_source, e_sink_1, l_sink, l_source_1, flag, ctr_source;
    extern int ctr_source_1, ctr_sink, ctr_sink1;

        SOURCE source;      /*C struct*/
        SINK sink;          /*C struct*/
        SOURCE_1 source_1;  /*C struct*/
        SINK_1 sink_1;      /*C struct*/

        HANDLE CHT[4];

        p = 0;
        e_source =  flag = 0;
        l_sink = e_sink_1 = l_source_1 = 1;
        max = 5;
        ctr_source = ctr_source_1 = ctr_sink = ctr_sink_1 = 0;

        /*Initialize FIFO*/
        F *f1 = fifo_init(10);
        F *f2 = fifo_init(10);

        /*Connect FIFO and modules*/
        source.output_source = f1;
        sink.input_sink = f1;

        sink_1.output_sink = f2;
        source_1.input_source = f2;

        /*Create Threads*/
        CHT[0] = (HANDLE)_beginthread((void (*)(void *))&SOURCE_out, 0, &f1);
        CHT[1] = (HANDLE)_beginthread((void (*)(void *))&SINK_in, 0, &f1);
        CHT[2] = (HANDLE)_beginthread((void (*)(void *))&SINK_out, 0, &f2);
        CHT[3] = (HANDLE)_beginthread((void (*)(void *))&SOURCE_in, 0, &f2);

        /* Wait until all threads have terminated */

        WaitForSingleObject(CHT[0], INFINITE);
        WaitForSingleObject(CHT[1], INFINITE);
        WaitForSingleObject(CHT[2], INFINITE);
        WaitForSingleObject(CHT[3], INFINITE);

        getchar();

        return 0;}

我读到 WaitForSingleObject 函数不适用于 _beginthread.... 但我的函数不是 nunsigned __stdcall 类型...

我构建的程序没有错误,我使用断点来测试它,它没问题。 当我编译我有这个问题:

线程“Win32 线程”(0x11ec) 已退出,代码为 0 (0x0)。 线程“Win32 线程”(0x918) 已退出,代码为 0 (0x0)。 线程“Win32 线程”(0x8a4) 已退出,代码为 0 (0x0)。 线程“Win32 线程”(0x2a8) 已退出,代码为 -1073741510 (0xc000013a)。 线程“Win32 线程”(0x12f8) 已退出,代码为 -1073741510 (0xc000013a)。 程序“[3984] SW=SW.exe: Native”已退出,代码为 -1073741510 (0xc000013a)。

程序永远不会到达函数 getchar()

在做这个程序之前,我做了一个程序,在两个块之间进行通信,一个读取,另一个写入。在那种情况下,我没有问题。

如果我不使用 WaitForSingleObject 函数,问题就会消失,但我的程序几乎总是在完成之前停止。

每个线程使用的函数在中断时停止。 但我希望其他的继续,直到它出现中断..

【问题讨论】:

  • 输出中没有明显问题,您只需键入 Ctrl+C 即可停止程序。 WaitForSingleObject() 与 _beginthread() 不可靠,但它肯定会在大多数情况下工作。防止您的代码到达 getchar()。看起来至少有一个线程没有退出条件,我们看不到它。
  • 当我不使用 WaitForSingleObject 函数时,程序没问题。但是,它不能很好地工作。我认为主线程在子线程函数返回之前终止。

标签: c windows


【解决方案1】:

_beginthread 的文档说明您不能使用其中一种等待功能:

以下示例代码演示了如何将 _beginthreadex 返回的线程句柄与同步 API WaitForSingleObject 一起使用。主线程在继续之前等待第二个线程终止。当第二个线程调用 _endthreadex 时,它会导致其线程对象进入信号状态。这允许主线程继续运行。 _beginthread 和 _endthread 无法做到这一点,因为 _endthread 调用 CloseHandle,在线程对象设置为信号状态之前将其销毁。

本文也给了你解决方案,即改用_beginthreadex

当你说这个问题时,我认为你在暗示这个问题

但我的函数不是 __stdcall

您只需更改您的函数以使用__stdcall 调用约定。

【讨论】:

  • 您好,如何将函数 void* SOURCE_in(struct SOURCE_1*) 更改为 _srdcall?
  • void* __stdcall SOURCE_in(struct SOURCE_1*)
  • 它不起作用...函数应该是:unsigned ( __stdcall *start_address )( void * )..
  • 然后更改返回类型以匹配所需的原型
  • 你别无选择。您必须使用匹配的原型。使您的界面适应 beginthreadex 的界面
【解决方案2】:

我不知道这是否有帮助,但您可能想尝试一下。我认为 WaitForSingleObject 仅适用于 Windows API。因此,您需要使用CreateThread 创建线程(您可以在 tge MSDN 中搜索 API,它比 beginthread 稍微复杂一些,但并不复杂,大多数不熟悉的结构可以设置为 NULL,如果您不了解安全性和类似)。 CreateThread 返回一个可以等待的句柄。

我认为beginthread 返回了一些你不能等待的东西,也就是说,WaitForSingleObject 的行为将是未定义的。在这种情况下,它可能会永远等待,因此不会调用 getchar。

【讨论】:

  • 当我使用 CreateThread 时,由于参数列表中的结构而出现错误。
猜你喜欢
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-23
  • 2014-01-20
  • 2011-04-18
  • 2011-02-12
  • 1970-01-01
相关资源
最近更新 更多