如何使用 for 循环创建多个 pthread?
How to create multiple pthreads with a for loop?
这应该是一项简单的任务,但我无法让它工作。下面的代码应该是不言自明的,我正在尝试创建 4 个线程,每个线程打印一个与我在 printMessage 中定义的数组不同的字符串。
#include <pthread.h>
#include <iostream>
using namespace std;
void *printMessage(void *arg)
{
int argInt = *((int*) arg);
const char* my_messages[4] = {"English: Hello!",
"French: Bonjour!", "Spanish: Hola!",
"German: Guten Tag!" };
cout << my_messages[argInt] << "\n";
pthread_exit(0);
}
int main()
{
pthread_t id[4];
int rc;
// Create thread(s)
for(int i = 0; i < 4; i++) {
int index = i;
rc = pthread_create(&id[index], NULL, printMessage, (void*) &index);
if (rc) {
cout << "ERROR; return code from pthread_create() is " << rc << endl;
return -1;
}
}
pthread_exit(0);
}
执行此操作时,数组中的最后一个字符串“German: Guten Tag!”打印了 4 次。我注意到的另一个奇怪的情况是,如果我放弃看似多余的 'index' 变量并使用 'i' 代替,则不会打印任何内容。作为 c++ 和多线程的新手,这让我很困惑,我们将不胜感激。谢谢!
rc = pthread_create(&id[index], NULL, printMessage, (void*) &index);
这将创建一个新的执行线程,并将指向名为 index
.
的局部变量的指针作为参数传递给它
您绝对不能保证新的执行线程实际上在 pthread_create
returns 之前开始执行,或者 之后立即开始执行 。通常在新的执行线程开始运行之前会有一小段延迟。您可以保证的是,新的执行线程将 运行、真正启动 。
与此同时,pthread_create()
returns 到达循环的末尾,传递指针的 index
变量被销毁并消失在黑洞中再也见不到了。一段时间后,新的执行线程开始搅动,获取其线程参数,该参数现在指向一个已销毁的对象。未定义的行为。
您有多种选择。
使用new
在动态范围内分配线程参数(并在完成后让执行线程delete
成为new
ed对象)。
使用额外的多线程资源,比如mutex和condition variables,来协调创建新执行线程的歌舞,让父执行线程一直等到新的执行线程读取其参数,并将其放在手边。
您将 int index
定义为循环体内的局部变量,因此它将在 pthread_create()
退出后超出范围,因此 printMessage()
显示 未定义的行为 通过访问无效内存(内存可能在每次循环迭代中被重用)。
您需要:
- 将
index
值移动到循环之前声明的数组中,并保留在范围内,直到所有线程都终止。就像你在处理 id[]
数组一样。
#include <pthread.h>
#include <iostream>
using namespace std;
void* printMessage(void *arg)
{
int argInt = *static_cast<int*>(arg);
const char* my_messages[4] = {"English: Hello!",
"French: Bonjour!", "Spanish: Hola!",
"German: Guten Tag!" };
cout << my_messages[argInt] << "\n";
return NULL;
}
int main()
{
pthread_t id[4];
int index[4];
int rc, num = 0;
// Create thread(s)
for(int i = 0; i < 4; i++) {
index[i] = i;
rc = pthread_create(&id[i], NULL, printMessage, &index[i]);
if (rc) {
cout << "ERROR; return code from pthread_create() is " << rc << endl;
break;
}
++num;
}
// wait for threads to terminate ...
for(int i = 0; i < num; i++) {
pthread_join(id[i], NULL);
}
return 0;
}
- 将
index
的 值 传递给每个线程,而不是将 指针 传递给 index
。
#include <pthread.h>
#include <iostream>
using namespace std;
void* printMessage(void *arg)
{
int argInt = reinterpret_cast<int>(arg);
const char* my_messages[4] = {"English: Hello!",
"French: Bonjour!", "Spanish: Hola!",
"German: Guten Tag!" };
cout << my_messages[argInt] << "\n";
return NULL;
}
int main()
{
pthread_t id[4];
int rc, num = 0;
// Create thread(s)
for(int i = 0; i < 4; i++) {
rc = pthread_create(&id[i], NULL, printMessage, reinterpret_cast<void*>(i));
if (rc) {
cout << "ERROR; return code from pthread_create() is " << rc << endl;
break;
}
++num;
}
// wait for threads to terminate ...
for(int i = 0; i < num; i++) {
pthread_join(id[i], NULL);
}
return 0;
}
- 动态分配
index
,让线程销毁传入的int
。
#include <pthread.h>
#include <iostream>
using namespace std;
void* printMessage(void *arg)
{
int *argInt = static_cast<int*>(arg);
const char* my_messages[4] = {"English: Hello!",
"French: Bonjour!", "Spanish: Hola!",
"German: Guten Tag!" };
cout << my_messages[*argInt] << "\n";
delete argInt;
return NULL;
}
int main()
{
pthread_t id[4];
int rc, num = 0;
// Create thread(s)
for(int i = 0; i < 4; i++) {
int *index = new int(i);
rc = pthread_create(&id[i], NULL, printMessage, index);
if (rc) {
cout << "ERROR; return code from pthread_create() is " << rc << endl;
delete index;
break;
}
++num;
}
// wait for threads to terminate ...
for(int i = 0; i < num; i++) {
pthread_join(id[i], NULL);
}
return 0;
}
话虽这么说,您确实应该直接使用 std::thread
而不是 pthreads
(如果需要,让 std::thread
实现在内部使用 pthreads
):
#include <iostream>
#include <thread>
using namespace std;
void printMessage(int arg)
{
const char* my_messages[4] = {"English: Hello!",
"French: Bonjour!", "Spanish: Hola!",
"German: Guten Tag!" };
cout << my_messages[arg] << "\n";
}
int main()
{
thread thrd[4];
// Create thread(s)
for(int i = 0; i < 4; i++) {
thrd[i] = thread(printMessage, i);
}
// wait for threads to terminate ...
for(int i = 0; i < 4; i++) {
thrd[i].join();
}
return 0;
}
这应该是一项简单的任务,但我无法让它工作。下面的代码应该是不言自明的,我正在尝试创建 4 个线程,每个线程打印一个与我在 printMessage 中定义的数组不同的字符串。
#include <pthread.h>
#include <iostream>
using namespace std;
void *printMessage(void *arg)
{
int argInt = *((int*) arg);
const char* my_messages[4] = {"English: Hello!",
"French: Bonjour!", "Spanish: Hola!",
"German: Guten Tag!" };
cout << my_messages[argInt] << "\n";
pthread_exit(0);
}
int main()
{
pthread_t id[4];
int rc;
// Create thread(s)
for(int i = 0; i < 4; i++) {
int index = i;
rc = pthread_create(&id[index], NULL, printMessage, (void*) &index);
if (rc) {
cout << "ERROR; return code from pthread_create() is " << rc << endl;
return -1;
}
}
pthread_exit(0);
}
执行此操作时,数组中的最后一个字符串“German: Guten Tag!”打印了 4 次。我注意到的另一个奇怪的情况是,如果我放弃看似多余的 'index' 变量并使用 'i' 代替,则不会打印任何内容。作为 c++ 和多线程的新手,这让我很困惑,我们将不胜感激。谢谢!
rc = pthread_create(&id[index], NULL, printMessage, (void*) &index);
这将创建一个新的执行线程,并将指向名为 index
.
您绝对不能保证新的执行线程实际上在 pthread_create
returns 之前开始执行,或者 之后立即开始执行 。通常在新的执行线程开始运行之前会有一小段延迟。您可以保证的是,新的执行线程将 运行、真正启动 。
与此同时,pthread_create()
returns 到达循环的末尾,传递指针的 index
变量被销毁并消失在黑洞中再也见不到了。一段时间后,新的执行线程开始搅动,获取其线程参数,该参数现在指向一个已销毁的对象。未定义的行为。
您有多种选择。
使用
new
在动态范围内分配线程参数(并在完成后让执行线程delete
成为new
ed对象)。使用额外的多线程资源,比如mutex和condition variables,来协调创建新执行线程的歌舞,让父执行线程一直等到新的执行线程读取其参数,并将其放在手边。
您将 int index
定义为循环体内的局部变量,因此它将在 pthread_create()
退出后超出范围,因此 printMessage()
显示 未定义的行为 通过访问无效内存(内存可能在每次循环迭代中被重用)。
您需要:
- 将
index
值移动到循环之前声明的数组中,并保留在范围内,直到所有线程都终止。就像你在处理id[]
数组一样。
#include <pthread.h>
#include <iostream>
using namespace std;
void* printMessage(void *arg)
{
int argInt = *static_cast<int*>(arg);
const char* my_messages[4] = {"English: Hello!",
"French: Bonjour!", "Spanish: Hola!",
"German: Guten Tag!" };
cout << my_messages[argInt] << "\n";
return NULL;
}
int main()
{
pthread_t id[4];
int index[4];
int rc, num = 0;
// Create thread(s)
for(int i = 0; i < 4; i++) {
index[i] = i;
rc = pthread_create(&id[i], NULL, printMessage, &index[i]);
if (rc) {
cout << "ERROR; return code from pthread_create() is " << rc << endl;
break;
}
++num;
}
// wait for threads to terminate ...
for(int i = 0; i < num; i++) {
pthread_join(id[i], NULL);
}
return 0;
}
- 将
index
的 值 传递给每个线程,而不是将 指针 传递给index
。
#include <pthread.h>
#include <iostream>
using namespace std;
void* printMessage(void *arg)
{
int argInt = reinterpret_cast<int>(arg);
const char* my_messages[4] = {"English: Hello!",
"French: Bonjour!", "Spanish: Hola!",
"German: Guten Tag!" };
cout << my_messages[argInt] << "\n";
return NULL;
}
int main()
{
pthread_t id[4];
int rc, num = 0;
// Create thread(s)
for(int i = 0; i < 4; i++) {
rc = pthread_create(&id[i], NULL, printMessage, reinterpret_cast<void*>(i));
if (rc) {
cout << "ERROR; return code from pthread_create() is " << rc << endl;
break;
}
++num;
}
// wait for threads to terminate ...
for(int i = 0; i < num; i++) {
pthread_join(id[i], NULL);
}
return 0;
}
- 动态分配
index
,让线程销毁传入的int
。
#include <pthread.h>
#include <iostream>
using namespace std;
void* printMessage(void *arg)
{
int *argInt = static_cast<int*>(arg);
const char* my_messages[4] = {"English: Hello!",
"French: Bonjour!", "Spanish: Hola!",
"German: Guten Tag!" };
cout << my_messages[*argInt] << "\n";
delete argInt;
return NULL;
}
int main()
{
pthread_t id[4];
int rc, num = 0;
// Create thread(s)
for(int i = 0; i < 4; i++) {
int *index = new int(i);
rc = pthread_create(&id[i], NULL, printMessage, index);
if (rc) {
cout << "ERROR; return code from pthread_create() is " << rc << endl;
delete index;
break;
}
++num;
}
// wait for threads to terminate ...
for(int i = 0; i < num; i++) {
pthread_join(id[i], NULL);
}
return 0;
}
话虽这么说,您确实应该直接使用 std::thread
而不是 pthreads
(如果需要,让 std::thread
实现在内部使用 pthreads
):
#include <iostream>
#include <thread>
using namespace std;
void printMessage(int arg)
{
const char* my_messages[4] = {"English: Hello!",
"French: Bonjour!", "Spanish: Hola!",
"German: Guten Tag!" };
cout << my_messages[arg] << "\n";
}
int main()
{
thread thrd[4];
// Create thread(s)
for(int i = 0; i < 4; i++) {
thrd[i] = thread(printMessage, i);
}
// wait for threads to terminate ...
for(int i = 0; i < 4; i++) {
thrd[i].join();
}
return 0;
}