C:在执行任何操作之前打印出多个线程的 ID?
C: Printing out multiple threads' ID's before they execute anything?
我想根据用户希望创建的线程数生成多个线程,并且这些线程中的每一个都执行一个函数“readFiles”。但是,在每个线程都可以执行 readFiles 中的任何有意义的代码(由“...”表示)之前,我希望所有线程都在一种介绍性通知消息中打印出它们的线程 ID,所以像...
"Thread ID _____ is processing!"
"Thread ID _____ is processing!"
"Thread ID _____ is processing!"
...
...
...
...但显然使用我的代码,每个线程一次只有 运行ning 个,因此线程 ID 仅在每个新线程开始执行有意义的代码时打印出来,所以这个。 ..
"Thread ID _____ is processing!"
...
"Thread ID _____ is processing!"
...
"Thread ID _____ is processing!"
...
在我对每个特定的新线程调用 pthread_create() 之前,有没有办法获取线程 ID?或者有没有一种方法可以使这些线程(应该 运行 同时),推迟或暂停它们在 readFiles (它们的“...”)中执行有意义的代码,直到它们有每个都先打印出线程 ID 消息?非常感谢大家!!!这是我的代码,可以让您更好地了解我目前拥有的东西...
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
uint64_t gettid()
{
pthread_t actual_tid = pthread_self();
uint64_t threadId = 0;
memcpy( &threadId, &actual_tid, sizeof( actual_tid ) );
return threadId;
}
void *readFiles( void *args )
{
pthread_mutex_lock(&mutex);
uint64_t current_id = gettid();
printf("Thread id = ");
printf("%" PRIu64 , current_id );
...
...
...
pthread_mutex_unlock(&mutex);
}
void alphabetcountmulthreads(int num_threads)
{
pthread_t ids[num_threads];
for ( int t = 0; t < num_threads; t++ )
{
if ( pthread_create( &ids[t], NULL, &readFiles, NULL ) != 0 )
{
fprintf( stderr, "error: Cannot create thread # %d\n", t );
break;
}
}
for ( int u = 0; u < num_threads; ++u )
{
if ( pthread_join( ids[u], NULL ) != 0 )
{
fprintf( stderr, "error: Cannot join thread # %d\N", u );
}
}
}
您可以通过多种方式完成此操作。您可以使用信号——让每个线程向某种监视器线程发送信号,然后等待被告知 运行。一旦监控线程收到所有信号,它就会通知等待线程继续。您还可以使用条件变量或互斥锁实现类似的解决方案来锁定线程,直到所有线程都打印出它们的 ID。
实现线程池的一种简单方法是,在所有线程开始实际工作之前,每个线程都有机会进行准备工作,即具有额外的启动互斥体、关联的条件变量和就绪线程的计数器:
static pthread_mutex_t prep_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t prep_cond = PTHREAD_COND_INITIALIZER;
static volatile size_t prep_count = 0;
static pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER;
static volatile size_t thread_count = 0;
static inline pid_t gettid(void) { return syscall(SYS_gettid); }
static void *thread_function(void *idref)
{
/* Get the number/index of this thread. */
const size_t num = *(pid_t *)idref;
const pid_t tid = gettid();
/* Replace it with the Linux tid. */
*(pid_t *)idref = tid;
/* Block here until preparatory work can be done. */
pthread_mutex_lock(&prep_mutex);
printf("Thread %zu of %zu has started.\n", id + 1, thread_count);
fflush(stdout);
prep_count++;
pthread_cond_signal(&prep_cond);
pthread_mutex_unlock(&prep_mutex);
/* Block until actual work can start. */
pthread_mutex_lock(&thread_mutex);
...
创建线程池时,创建者持有两个互斥量。当它准备好让线程开始准备工作时,它释放 prep_mutex
,等待 prep_cond
直到足够数量的线程完成准备工作(prep_count
足够高)。然后,它释放 thread_mutex
.
int start_threads(size_t max_count)
{
pthread_t thread_id[max_count];
pid_t linux_tid[max_count];
pthread_attr_t attrs;
int err = 0;
/* Assume no threads currently running */
prep_count = thread_count = 0;
/* Shrink stack size; the default is too large. */
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, 2*PTHREAD_STACK_MIN);
/* Grab the mutexes, so the threads will block initially. */
pthread_mutex_lock(&prep_mutex);
pthread_mutex_lock(&thread_mutex);
while (thread_count < max_count) {
linux_tid[thread_count] = thread_count;
err = pthread_create(thread_id + thread_count, &attrs,
thread_function, linux_tid + thread_count);
if (err)
break;
thread_count++;
}
/* Attributes are no longer needed. */
pthread_attr_destroy(&attrs);
/* No threads created at all? */
if (thread_count < 1) {
pthread_mutex_unlock(&prep_mutex);
pthread_mutex_unlock(&thread_mutex);
/* Return failure. */
return err;
}
/* All threads have now been created; let them do prep work. */
while (prep_count < thread_count) {
pthread_cond_wait(&prep_cond, &prep_mutex);
}
pthread_mutex_unlock(&prep_mutex);
/* All threads have finished their prep work; start working. */
pthread_mutex_unlock(&thread_mutex);
...
上面最多创建 max_num
个线程,它们的 pthread ID 在 thread_id[]
中,它们的 Linux 个线程在 linux_tid[]
.
中
当线程启动时,它会获得一个指向存储 Linux tid 的位置的指针。最初,它包含线程的索引(“线程号”,从 0 开始),因此 thread_function
将其抓取为 num
,获得 Linux tid 作为 tid
,并将其存储到作为参数给定的位置。这样,原始线程和创建的线程都知道索引(num
)、pthread ID(thread_id[]
、pthread_self()
)和Linux tid(linux_tid[]
和 tid
).
注意数组在 pthread_create()
调用中是如何取消引用的。如果 array
是一个数组,并且 index
是它的索引,那么 &(array[index]) == array + index
.
上面,start_threads()
函数不假设它可以启动所有max_num
个线程。如果无法创建任何线程,它会使用非零 errno
数字执行 return,但如果它可以创建至少一个线程,一旦线程可以获取 prep_mutex
,thread_count
将反映他们帮派中正确的线程数。 (没有理由仅仅因为您只能创建 53 个工作线程而不是 54 个而失败。)
我想根据用户希望创建的线程数生成多个线程,并且这些线程中的每一个都执行一个函数“readFiles”。但是,在每个线程都可以执行 readFiles 中的任何有意义的代码(由“...”表示)之前,我希望所有线程都在一种介绍性通知消息中打印出它们的线程 ID,所以像...
"Thread ID _____ is processing!"
"Thread ID _____ is processing!"
"Thread ID _____ is processing!"
...
...
...
...但显然使用我的代码,每个线程一次只有 运行ning 个,因此线程 ID 仅在每个新线程开始执行有意义的代码时打印出来,所以这个。 ..
"Thread ID _____ is processing!"
...
"Thread ID _____ is processing!"
...
"Thread ID _____ is processing!"
...
在我对每个特定的新线程调用 pthread_create() 之前,有没有办法获取线程 ID?或者有没有一种方法可以使这些线程(应该 运行 同时),推迟或暂停它们在 readFiles (它们的“...”)中执行有意义的代码,直到它们有每个都先打印出线程 ID 消息?非常感谢大家!!!这是我的代码,可以让您更好地了解我目前拥有的东西...
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
uint64_t gettid()
{
pthread_t actual_tid = pthread_self();
uint64_t threadId = 0;
memcpy( &threadId, &actual_tid, sizeof( actual_tid ) );
return threadId;
}
void *readFiles( void *args )
{
pthread_mutex_lock(&mutex);
uint64_t current_id = gettid();
printf("Thread id = ");
printf("%" PRIu64 , current_id );
...
...
...
pthread_mutex_unlock(&mutex);
}
void alphabetcountmulthreads(int num_threads)
{
pthread_t ids[num_threads];
for ( int t = 0; t < num_threads; t++ )
{
if ( pthread_create( &ids[t], NULL, &readFiles, NULL ) != 0 )
{
fprintf( stderr, "error: Cannot create thread # %d\n", t );
break;
}
}
for ( int u = 0; u < num_threads; ++u )
{
if ( pthread_join( ids[u], NULL ) != 0 )
{
fprintf( stderr, "error: Cannot join thread # %d\N", u );
}
}
}
您可以通过多种方式完成此操作。您可以使用信号——让每个线程向某种监视器线程发送信号,然后等待被告知 运行。一旦监控线程收到所有信号,它就会通知等待线程继续。您还可以使用条件变量或互斥锁实现类似的解决方案来锁定线程,直到所有线程都打印出它们的 ID。
实现线程池的一种简单方法是,在所有线程开始实际工作之前,每个线程都有机会进行准备工作,即具有额外的启动互斥体、关联的条件变量和就绪线程的计数器:
static pthread_mutex_t prep_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t prep_cond = PTHREAD_COND_INITIALIZER;
static volatile size_t prep_count = 0;
static pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER;
static volatile size_t thread_count = 0;
static inline pid_t gettid(void) { return syscall(SYS_gettid); }
static void *thread_function(void *idref)
{
/* Get the number/index of this thread. */
const size_t num = *(pid_t *)idref;
const pid_t tid = gettid();
/* Replace it with the Linux tid. */
*(pid_t *)idref = tid;
/* Block here until preparatory work can be done. */
pthread_mutex_lock(&prep_mutex);
printf("Thread %zu of %zu has started.\n", id + 1, thread_count);
fflush(stdout);
prep_count++;
pthread_cond_signal(&prep_cond);
pthread_mutex_unlock(&prep_mutex);
/* Block until actual work can start. */
pthread_mutex_lock(&thread_mutex);
...
创建线程池时,创建者持有两个互斥量。当它准备好让线程开始准备工作时,它释放 prep_mutex
,等待 prep_cond
直到足够数量的线程完成准备工作(prep_count
足够高)。然后,它释放 thread_mutex
.
int start_threads(size_t max_count)
{
pthread_t thread_id[max_count];
pid_t linux_tid[max_count];
pthread_attr_t attrs;
int err = 0;
/* Assume no threads currently running */
prep_count = thread_count = 0;
/* Shrink stack size; the default is too large. */
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, 2*PTHREAD_STACK_MIN);
/* Grab the mutexes, so the threads will block initially. */
pthread_mutex_lock(&prep_mutex);
pthread_mutex_lock(&thread_mutex);
while (thread_count < max_count) {
linux_tid[thread_count] = thread_count;
err = pthread_create(thread_id + thread_count, &attrs,
thread_function, linux_tid + thread_count);
if (err)
break;
thread_count++;
}
/* Attributes are no longer needed. */
pthread_attr_destroy(&attrs);
/* No threads created at all? */
if (thread_count < 1) {
pthread_mutex_unlock(&prep_mutex);
pthread_mutex_unlock(&thread_mutex);
/* Return failure. */
return err;
}
/* All threads have now been created; let them do prep work. */
while (prep_count < thread_count) {
pthread_cond_wait(&prep_cond, &prep_mutex);
}
pthread_mutex_unlock(&prep_mutex);
/* All threads have finished their prep work; start working. */
pthread_mutex_unlock(&thread_mutex);
...
上面最多创建 max_num
个线程,它们的 pthread ID 在 thread_id[]
中,它们的 Linux 个线程在 linux_tid[]
.
当线程启动时,它会获得一个指向存储 Linux tid 的位置的指针。最初,它包含线程的索引(“线程号”,从 0 开始),因此 thread_function
将其抓取为 num
,获得 Linux tid 作为 tid
,并将其存储到作为参数给定的位置。这样,原始线程和创建的线程都知道索引(num
)、pthread ID(thread_id[]
、pthread_self()
)和Linux tid(linux_tid[]
和 tid
).
注意数组在 pthread_create()
调用中是如何取消引用的。如果 array
是一个数组,并且 index
是它的索引,那么 &(array[index]) == array + index
.
上面,start_threads()
函数不假设它可以启动所有max_num
个线程。如果无法创建任何线程,它会使用非零 errno
数字执行 return,但如果它可以创建至少一个线程,一旦线程可以获取 prep_mutex
,thread_count
将反映他们帮派中正确的线程数。 (没有理由仅仅因为您只能创建 53 个工作线程而不是 54 个而失败。)