c - 多线程程序中线程的执行顺序

标签 c multithreading pthreads

我对线程编码非常陌生,所以我正在做一个我在网上找到的练习,它要求这样的东西:

编写一个程序 hellomany.c,它将创建命令行中指定的 N 个线程,每个线程打印出一条 hello 消息及其自己的线程 ID。要查看线程的执行如何交错,请让主线程每创建 4 或 5 个线程就休眠 1 秒。代码的输出应类似于:

   I am thread 1. Created new thread (4) in iteration 0...
   Hello from thread 4 - I was created in iteration 0
   I am thread 1. Created new thread (6) in iteration 1...
   I am thread 1. Created new thread (7) in iteration 2...
   I am thread 1. Created new thread (8) in iteration 3...
   I am thread 1. Created new thread (9) in iteration 4...
   I am thread 1. Created new thread (10) in iteration 5...
   Hello from thread 6 - I was created in iteration 1
   Hello from thread 7 - I was created in iteration 2
   Hello from thread 8 - I was created in iteration 3
   Hello from thread 9 - I was created in iteration 4
   Hello from thread 10 - I was created in iteration 5
   I am thread 1. Created new thread (11) in iteration 6...
   I am thread 1. Created new thread (12) in iteration 7...
   Hello from thread 11 - I was created in iteration 6
   Hello from thread 12 - I was created in iteration 7

我成功编写的代码是这样的:

#include <stdio.h>       
#include <stdlib.h>
#include <pthread.h>     

void* PrintHello(int iteration)
{
    printf("Hello from thread %u - I was created in iteration %d \n", 
    pthread_self(), iteration);
    pthread_exit(NULL);                 
}

int main(void)
{
    int        rc;                
    pthread_t  thread_id;             
    int        tidMain;
    int        n, i;

    tidMain = pthread_self();

    printf("How many threads are there to be created?\n");
    scanf("%d", &n);

    for(i = 1; i <= n; i++) {

        pthread_t thread_id;
        rc = pthread_create(&thread_id, NULL, PrintHello, i);
        printf("I am thread %u. Created new thread (%u) in iteration %d\n", 
        tidMain, thread_id, i);
        if(rc)                             
        {
            printf("\n ERROR: return code from pthread_create is %d \n", rc);
            exit(1);
        }
        if((i % 5) == 0) {
            sleep(1);
        }

    }

    pthread_exit(NULL);
}

该程序确实打印了我想要的内容,甚至每创建 5 个线程就会休眠并“中断”创建;不过,我不知道为什么,但是当每个创建的线程在 5-thread-printing-streak 中被执行时(在主线程通知它们已被创建之后),我首先要执行“问候”的线程是最后创建的线程。我从控制台得到的,即当我要求它创建 8 个线程时,是这样的:

I am thread 3075630848. Created new thread (3075627840) in iteration 1
I am thread 3075630848. Created new thread (3067235136) in iteration 2
I am thread 3075630848. Created new thread (3058842432) in iteration 3
I am thread 3075630848. Created new thread (3050449728) in iteration 4
I am thread 3075630848. Created new thread (3042057024) in iteration 5
Hello from thread 3042057024 - I was created in iteration 5 
Hello from thread 3050449728 - I was created in iteration 4 
Hello from thread 3058842432 - I was created in iteration 3 
Hello from thread 3067235136 - I was created in iteration 2 
Hello from thread 3075627840 - I was created in iteration 1 
I am thread 3075630848. Created new thread (3032480576) in iteration 6
I am thread 3075630848. Created new thread (3024087872) in iteration 7
I am thread 3075630848. Created new thread (3015695168) in iteration 8
Hello from thread 3015695168 - I was created in iteration 8 
Hello from thread 3024087872 - I was created in iteration 7 
Hello from thread 3032480576 - I was created in iteration 6

据我了解,它首先执行最后创建的线程。为什么会出现这种情况?我可以让它先执行第一个创建的吗?

顺便说一句:我在 Ubuntu 上运行

最佳答案

这就是并发编程的要点。您永远不能对线程的执行顺序做出任何假设。例如,我得到以下输出:

I am thread 639280960. Created new thread (630781696) in iteration 1
Hello from thread 630781696 - I was created in iteration 1
I am thread 639280960. Created new thread (622388992) in iteration 2
Hello from thread 622388992 - I was created in iteration 2
I am thread 639280960. Created new thread (613996288) in iteration 3
Hello from thread 613996288 - I was created in iteration 3
I am thread 639280960. Created new thread (536868608) in iteration 4
Hello from thread 536868608 - I was created in iteration 4
I am thread 639280960. Created new thread (526280448) in iteration 5
Hello from thread 526280448 - I was created in iteration 5
I am thread 639280960. Created new thread (517887744) in iteration 6
I am thread 639280960. Created new thread (509495040) in iteration 7
Hello from thread 509495040 - I was created in iteration 7
I am thread 639280960. Created new thread (501102336) in iteration 8
Hello from thread 501102336 - I was created in iteration 8
Hello from thread 517887744 - I was created in iteration 6

如果我再次运行它,我可能会得到不同的输出。自己尝试一下!

Wikipedia Article about Concurrent computing ,表示以下内容:

The exact timing of when tasks in a concurrent system are executed depend on the scheduling, and tasks need not always be executed concurrently. For example, given two tasks, T1 and T2:

  • T1 may be executed and finished before T2 or vice versa (serial and sequential)

  • T1 and T2 may be executed alternately (serial and concurrent)

  • T1 and T2 may be executed simultaneously at the same instant of time (parallel and concurrent)

我建议您阅读一些有关并发和并行性的基础文章或文献。

关于c - 多线程程序中线程的执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51414697/

相关文章:

c# - 从主线程调用 WPF 窗口中的方法

c - 如何从父线程中杀死子线程 - C

预处理器后的 C 代码

c - 如果功能为真,如何保留值(value)?

java - 使用实例变量 java 的多线程

c# - 多写者单读者并发模型的最有效锁?

c - 在信号处理程序中使用 `pause()` 有什么缺陷?

c++ - 如何使用 pthreads 以正确的方式设置两个线程之一的优先级

X509_V_FLAG_PARTIAL_CHAIN 的 cURL 简单选项

c++ - 为什么我不能使用两个scanf函数来输入字母