我对线程编码还很陌生,所以我正在做一个练习,我在网上找到了,该练习要求这样的事情:
编写一个程序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线程打印条纹中被执行时(在主线程通知它们已经创建之后), “打招呼”的线程是最后创建的线程。我从控制台获得的信息,即当我要求它创建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上运行
答案 0 :(得分:1)
这是关于并发编程的要点。您永远无法对线程执行的顺序进行任何假设。例如,我得到以下输出:
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说:
在并发系统中执行任务的确切时间 取决于调度,任务不一定总是执行 同时。例如,给定两个任务T1和T2:
T1可以在T2之前执行并结束,反之亦然(顺序和顺序)
T1和T2可以交替执行(串行和并发)
T1和T2可以在同一时间(并行和并发)同时执行
我建议您阅读一些有关并发和并行性的基本文章或文献。
答案 1 :(得分:1)
这是一个并发程序。如果您多次运行程序,则即使在同一主机中,顺序也会有所不同。
顺便说一句,也许最好在编码之前先查看pthread
API。
对于pthread_create()
:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
第三个参数是void *(*start_routine)(void *)
而不是void *(start_routine)(int)
,第四个参数是void *
而不是int
。
答案 2 :(得分:1)
执行线程的顺序不确定。如果您需要特定的命令,则必须使用锁,互斥锁和条件来命令其执行以符合您的要求。
您看到的顺序是由硬件和内核(有时是随机性)引起的。我假设您只有一个单核CPU,否则输出将毫无意义。创建线程时,内核只需调度线程在以后运行,并继续执行主线程。因此,您会收到有关所有5个线程创建的消息。仅当主线程进入睡眠状态时,内核才会切换到准备运行的下一个线程。好像是FILO(先入后出)。这恰好是您硬件上的版本中的内核恰好要做的。随时可以更改。
另一方面,pOwl似乎具有多个核心。因此,当主线程创建线程时,其他内核已经执行了它们。或者他只是拥有不同的内核。