【问题标题】:C- POSIX Thread BasicsC-POSIX 线程基础
【发布时间】:2021-10-02 15:59:08
【问题描述】:

我正在学习 POSIX 线程的基础知识。我想创建一个打印“Hello World!”的程序10 次,每次打印输出之间延迟一秒。我已经使用 for 循环打印了 10 次,但我一直坚持如何实现时间延迟部分。

这是我目前的代码:

#define MAX 10

void* helloFunc(void* tid)
{
printf("Hello World!\n", (int)(intptr_t)tid);
}

int main(int ac, char * argv)
{
pthread_t hej[MAX];
for (int i = 0; i < MAX; i++)
{
    pthread_create(&hej[i], NULL, helloFunc, (void*)(intptr_t)i);
    pthread_join(&hej[i], NULL);
}
pthread_exit(NULL);
return(0);
}

提前致谢!

【问题讨论】:

  • printf("Hello World!\n", (int)tid); 无效,。要等待 1 秒,您可以使用 sleep(1),不要忘记 #include &lt;unistd.h&gt;

标签: c pthreads


【解决方案1】:

您的代码有两个主要问题:

  • 首先,您必须等待线程完成。你可以通过pthread_join加入他们来做到这一点。为此,您必须从每个线程(例如在数组中)保存 pthread_t 值。

    如果您不等待线程,那么 exit 调用将结束进程,这也会意外终止并结束进程中的所有线程。

    要让所有线程并行运行,您应该在创建它们后在单独的循环中等待:

    pthread_t hej[MAX];
    
    for (int i = 0; i < MAX; i++)
    {
        pthread_create(&hej[i], ...);
    }
    
    for (int i = 0; i < MAX; i++)
    {
        pthread_join(&hej[i], NULL);
    }
    
  • 第二个问题是你将一个 指针 传递给i 给线程,所以线程函数内部的tid 将都是相同的(并且是一个非常大和奇怪的值) .要传递一个值,您必须先将其转换为intptr_t,然后再转换为void *

    pthread_create(..., (void *) (intptr_t) i);
    

    并且在线程函数中你做相反的转换:

    printf("Hello World %d!\n", (int) (intptr_t) tid);
    

    请注意,这是一个例外,即永远不应将值作为指针(或相反)传递。


最后是“延迟”位...在 POSIX 系统上,有很多方法可以延迟执行或休眠。自然而简单的解决方案是使用休眠一秒钟的sleep(1)

问题是在哪里处理这个sleep(1) 调用。如果您在 printf 之后的线程函数中执行此操作,则所有线程将竞相打印消息,然后所有线程将同时休眠。

如果您在创建线程的循环中执行此操作,则线程不会真正并行运行,而是真正串行运行,其中一个线程打印消息并退出,然后main 线程将等待一秒钟在创建下一个线程之前。它使线程有点无用。

作为可能的第三种解决方案,使用传递给线程函数的值作为睡眠时间,因此第一个创建的线程(i == 0 时)将立即启动,第二个线程(i == 1 时)会睡一秒钟。以此类推,直到第十个线程被创建并在打印消息前休眠 9 秒。

可以这样做:

void* helloFunc(void* tid)
{
    int value = (int) (intptr_t) tid;
    sleep(value);
    printf("Hello World %d!\n", value);

    // Must return a value, as the function is declared as such
    return NULL;
}

【讨论】:

  • 或者,如果他们在创建下一个线程之前加入每个线程(不要忘记在程序终止之前也加入最后一个线程),他们可以重用一个pthread_t。在一般情况下,这不是一个可行的解决方案,但它可以解决所提出的特定问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多