【问题标题】:get parameters of thread function c获取线程函数c的参数
【发布时间】:2017-10-20 03:21:24
【问题描述】:

我正在用 C 语言编写一个程序,其中有一些线程,问题是当我想从线程函数接收参数时。

结构如下:

struct parametro
{
  int pl;
};

这是线程函数:

DWORD WINAPI hijo(void *);

DWORD WINAPI hijo(void *p) 
{
  struct parametro* params = (struct parametro*)p;
  printf("\nPosicion %d", params->pl);
}

下面是创建线程的代码:

int i;
    for(i=0; i<32; i++)
    {
        struct parametro p;
        p.pl = i;
        hilo = CreateThread(NULL, 0, &hijo, &p, 0, NULL);
    }

它会返回这个:

Posicion 3
Posicion 5
Posicion 9
Posicion 15
Posicion 19
Posicion 23
Posicion 27
Posicion 30
Posicion 1
Posicion 1
Posicion 1
Posicion 1
Posicion 1
Posicion 1
Posicion 1
Posicion 1

每次代码运行时输出都不同。

我怎样才能做到这一点?

【问题讨论】:

  • 标准问题。您正在将 same 指针传递给所有线程。不保证线程在调用CreateThread 时运行。因此,当他们运行时,无法确定当时p 的值是多少。每个线程都需要一个单独的结构,
  • 另请注意,p 仅在 for 循环内有效。一旦该循环完成,传递给线程的所有指针都将变为无效。
  • 谢谢,那么我该怎么做才能分开structs
  • 通常的方法是 malloc() 为每个线程创建一个结构实例。线程可以在终止之前释放()它们(假设它们显式终止)。
  • .. 或者你可以把一堆东西弄得一团糟。

标签: c windows multithreading


【解决方案1】:

我已经解决了这个问题,我在第二个进程for 之后放置了一个system("pause"),看起来像for 在创建整个线程之前结束。

【讨论】:

  • 但我一开始就问你 - you not exit from create functions before all child threads exit ? 。如果您从函数中退出 - 所有局部变量(您传递给另一个线程的指针)都将变为无效。更准确地说,这里的数据可以随时被覆盖。所以你必须等到所有线程完成或最小端如何使用你的局部变量(比如信号事件)。和 system("pause") - 这不是解决方案。你需要等待确切地而不是随机时间
  • 是的,这是一个尝试,所有线程都会在一个无限循环中做其他事情,但我不知道为什么所有线程都是在for结束之前创建的......
  • 在这种情况下,最好为堆中的线程分配数据块,并在每个线程中释放它。函数中不使用局部变量,退出
【解决方案2】:

您可以创建线程特定的变量,为它们分配可以使用的值。例如

struct parametro p[32];

int i;

    for(i=0; i<32; i++)
    {
        p[i].pl = i;
        hilo = CreateThread(NULL, 0, &hijo, &p[i], 0, NULL);
    }

这将确保每个线程都获得一个特定的结构实例,该实例被初始化为所需的值。

【讨论】:

  • @AitorRamosPajares - 它收到了什么?你没有退出创建函数之前所有子线程退出? hilo = CreateThread 这是错误 - 你有句柄泄漏。需要或只是关闭手柄或将每个手柄存放在单独的位置
  • @AitorRamosPajares - 如果没有您当前的相关 src 代码,就不可能说出您的错误是什么
  • 是的但是太代码了,但是是两个进程,其中一个有32个线程,这个只做我写的代码,其他进程不干涉。
  • 我不确定printf 是线程安全的。将对printf 的调用放在临界区中,或者使用MessageBox 而不是printf。也不清楚您的程序是否在退出之前等待线程退出。您需要发布minimal reproducible example
  • @HarryJohnston - printf 是线程安全的。它调用关键部分内的实际代码 - example 实际代码当然可以从 crt 版本中进行一些更改,但在开始时调用 _lock_* 并在末尾调用 _unlock_* 没有改变。在内部这个锁定/解锁进入/离开临界区
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-15
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-12
  • 2011-08-15
相关资源
最近更新 更多