C 中的 PThreads,线程 ID 是如何生成的,为什么它们交替出现
PThreads in C, how are thread-IDs generated, why they alternate
我正在尝试使用 pthread_create() 创建 (3) 个线程,并按顺序打印线程编号和 ID,进行 (5) 次迭代。
请原谅我的代码,我是 C 的新手,但在打印我的线程创建时我看到了一个奇怪的模式。例如,我想要的输出是:
Iteration: 1 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 2 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 3 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 4 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 5 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
我的实际输出是:
Iteration: 1 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 2 of 5
Thread 1 (ID: 140671525238336) <-- Order starts reversing here for some reason
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671542023744)
Iteration: 3 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 4 of 5
Thread 1 (ID: 140671525238336)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671542023744)
Iteration: 5 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
非常感谢您的建议。这让我发疯。我的代码贴在下面:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
pthread_t threads[3];
pthread_mutex_t mutex;
void * printThread(void * arg) {
pthread_t id = pthread_self(); // Get pthread ID
printf("\t\tThread %d (ID: %ld)\n", arg + 1, id); // Print thread creation and ID, account for zero index
return NULL;
}
int main(void) {
int i, j;
int error;
if (pthread_mutex_init( & mutex, NULL) != 0) {
printf("\n Error: pthread_mutex_init failure. [%s]\n", strerror(error));
return 1;
} // Catch and print pthread_mutex_init error
printf("Begin multithreading...\n");
/* Create and print (3) threads by ID, for (5) iterations */
for (i = 0; i < 5; i++) {
printf("\t\nIteration: %d of 5\n\n", i + 1);
for (j = 0; j < 3; j++) {
error = pthread_create( & (threads[j]), NULL, & printThread, (void * ) j); // Create new thread
if (error != 0)
printf("\nError: pthread_create failure. [%s]\n", strerror(error));
sleep(2);
} // Catch and print pthread_create error
/* Syncrhonize threads */
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
pthread_join(threads[2], NULL);
}
printf("\nMultithreading complete.\n");
/* Cleanup threads and mutex */
pthread_exit( & threads);
pthread_mutex_destroy( & mutex);
return 0;
}
pthreads 是一个非常不透明和通用的 API,因此使用 pthreads API 的应用程序代码可以很容易地移植到尽可能多的(通常是截然不同的)平台上。
作为不透明哲学的一部分,pthreads 对 pthread_create()
返回的 ID 值的唯一限制是每个有效(即 not-yet-joined)线程的 ID 在尊重方面是唯一的到进程中的所有其他有效线程。除此之外,所有行为都留给平台的 pthreads 实现来处理,但它认为合适。
鉴于此,我认为发布的代码中没有任何错误。唯一的错误是假设 pthread_create()
返回的 ID 应该或将遵循一些超出 thread-ID-uniqueness 的附加规则——这不是一个有效的假设。
回答了我自己的问题。我能够通过从线程数组中打印它们来绕过我的线程创建的错误排序,而不是从我的 pthread 创建中的函数中打印出来。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int thread;
pthread_t threads[3]; // Initialize thread array
pthread_mutex_t mutex;
void * printThread() {
pthread_mutex_lock( & mutex); // Lock code
pthread_t tid = pthread_self(); // Get thread
printf("\nThread %d (thread-id: %ld) created successfully.", thread + 1,
tid); // Print thread creation, account for zero index
pthread_mutex_unlock( & mutex); // Unlock code
return NULL;
}
int main(void) {
int iteration;
int error;
if (pthread_mutex_init( & mutex, NULL) != 0) {
printf("\n Error: pthread_mutex_init failure. [%s]\n", strerror(error));
return 1;
} // Catch and print pthread_mutex_init error
printf("Begin multithreading...\n");
/* Create and print three (3) threads by thread-id */
for (thread = 0; thread < 3; thread++) {
error = pthread_create( & (threads[thread]), NULL, & printThread, NULL); // Create new thread
sleep(1); // Necessary to ensure proper order
if (error != 0)
printf("\nError: pthread_create failure. [%s]\n", strerror(error));
} // Catch and print pthread_create error
/* Synchronize threads */
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
pthread_join(threads[2], NULL);
/* Print three (3) threads, in turn, for five (5) iterations */
for (iteration = 0; iteration < 5; iteration++) {
printf("\n\n\tIteration: %d of 5 - \n", iteration + 1); // Account for zero index
for (thread = 0; thread < 3; thread++) {
printf("\n\t\tThread %d (thread-id: %ld)", thread + 1,
threads[thread]); // Print threads in turn, account for zero index
sleep(1); // Sleep to simulate thread step
}
}
printf("\n\nMultithreading complete.\n");
/* Cleanup mutex and threads */
pthread_mutex_destroy( & mutex);
pthread_exit( & threads);
return 0;
}
我正在尝试使用 pthread_create() 创建 (3) 个线程,并按顺序打印线程编号和 ID,进行 (5) 次迭代。
请原谅我的代码,我是 C 的新手,但在打印我的线程创建时我看到了一个奇怪的模式。例如,我想要的输出是:
Iteration: 1 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 2 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 3 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 4 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 5 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
我的实际输出是:
Iteration: 1 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 2 of 5
Thread 1 (ID: 140671525238336) <-- Order starts reversing here for some reason
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671542023744)
Iteration: 3 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
Iteration: 4 of 5
Thread 1 (ID: 140671525238336)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671542023744)
Iteration: 5 of 5
Thread 1 (ID: 140671542023744)
Thread 2 (ID: 140671533631040)
Thread 3 (ID: 140671525238336)
非常感谢您的建议。这让我发疯。我的代码贴在下面:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
pthread_t threads[3];
pthread_mutex_t mutex;
void * printThread(void * arg) {
pthread_t id = pthread_self(); // Get pthread ID
printf("\t\tThread %d (ID: %ld)\n", arg + 1, id); // Print thread creation and ID, account for zero index
return NULL;
}
int main(void) {
int i, j;
int error;
if (pthread_mutex_init( & mutex, NULL) != 0) {
printf("\n Error: pthread_mutex_init failure. [%s]\n", strerror(error));
return 1;
} // Catch and print pthread_mutex_init error
printf("Begin multithreading...\n");
/* Create and print (3) threads by ID, for (5) iterations */
for (i = 0; i < 5; i++) {
printf("\t\nIteration: %d of 5\n\n", i + 1);
for (j = 0; j < 3; j++) {
error = pthread_create( & (threads[j]), NULL, & printThread, (void * ) j); // Create new thread
if (error != 0)
printf("\nError: pthread_create failure. [%s]\n", strerror(error));
sleep(2);
} // Catch and print pthread_create error
/* Syncrhonize threads */
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
pthread_join(threads[2], NULL);
}
printf("\nMultithreading complete.\n");
/* Cleanup threads and mutex */
pthread_exit( & threads);
pthread_mutex_destroy( & mutex);
return 0;
}
pthreads 是一个非常不透明和通用的 API,因此使用 pthreads API 的应用程序代码可以很容易地移植到尽可能多的(通常是截然不同的)平台上。
作为不透明哲学的一部分,pthreads 对 pthread_create()
返回的 ID 值的唯一限制是每个有效(即 not-yet-joined)线程的 ID 在尊重方面是唯一的到进程中的所有其他有效线程。除此之外,所有行为都留给平台的 pthreads 实现来处理,但它认为合适。
鉴于此,我认为发布的代码中没有任何错误。唯一的错误是假设 pthread_create()
返回的 ID 应该或将遵循一些超出 thread-ID-uniqueness 的附加规则——这不是一个有效的假设。
回答了我自己的问题。我能够通过从线程数组中打印它们来绕过我的线程创建的错误排序,而不是从我的 pthread 创建中的函数中打印出来。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int thread;
pthread_t threads[3]; // Initialize thread array
pthread_mutex_t mutex;
void * printThread() {
pthread_mutex_lock( & mutex); // Lock code
pthread_t tid = pthread_self(); // Get thread
printf("\nThread %d (thread-id: %ld) created successfully.", thread + 1,
tid); // Print thread creation, account for zero index
pthread_mutex_unlock( & mutex); // Unlock code
return NULL;
}
int main(void) {
int iteration;
int error;
if (pthread_mutex_init( & mutex, NULL) != 0) {
printf("\n Error: pthread_mutex_init failure. [%s]\n", strerror(error));
return 1;
} // Catch and print pthread_mutex_init error
printf("Begin multithreading...\n");
/* Create and print three (3) threads by thread-id */
for (thread = 0; thread < 3; thread++) {
error = pthread_create( & (threads[thread]), NULL, & printThread, NULL); // Create new thread
sleep(1); // Necessary to ensure proper order
if (error != 0)
printf("\nError: pthread_create failure. [%s]\n", strerror(error));
} // Catch and print pthread_create error
/* Synchronize threads */
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
pthread_join(threads[2], NULL);
/* Print three (3) threads, in turn, for five (5) iterations */
for (iteration = 0; iteration < 5; iteration++) {
printf("\n\n\tIteration: %d of 5 - \n", iteration + 1); // Account for zero index
for (thread = 0; thread < 3; thread++) {
printf("\n\t\tThread %d (thread-id: %ld)", thread + 1,
threads[thread]); // Print threads in turn, account for zero index
sleep(1); // Sleep to simulate thread step
}
}
printf("\n\nMultithreading complete.\n");
/* Cleanup mutex and threads */
pthread_mutex_destroy( & mutex);
pthread_exit( & threads);
return 0;
}