出于某种原因,我认为在 main 函数末尾调用 pthread_exit(NULL)
将保证所有正在运行的线程(至少在 main 函数中创建)将在 之前完成运行main
可以退出。但是,当我在下面运行这段代码而不显式调用两个 pthread_join
函数(在 main
的末尾)时,我得到了一个段错误,这似乎是因为 main
函数在两个线程完成它们的工作之前已经退出,因此 char buffer 不再可用。但是,当我在 main
的末尾包含这两个 pthread_join
函数调用时,它会按预期运行。为了保证 main
不会在所有正在运行的线程完成之前退出,是否有必要为所有直接在 main
中初始化的线程显式调用 pthread_join
?
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
#include <semaphore.h>
#define NUM_CHAR 1024
#define BUFFER_SIZE 8
typedef struct {
pthread_mutex_t mutex;
sem_t full;
sem_t empty;
char* buffer;
} Context;
void *Reader(void* arg) {
Context* context = (Context*) arg;
for (int i = 0; i < NUM_CHAR; ++i) {
sem_wait(&context->full);
pthread_mutex_lock(&(context->mutex));
char c = context->buffer[i % BUFFER_SIZE];
pthread_mutex_unlock(&(context->mutex));
sem_post(&context->empty);
printf("%c", c);
}
printf("\n");
return NULL;
}
void *Writer(void* arg) {
Context* context = (Context*) arg;
for (int i = 0; i < NUM_CHAR; ++i) {
sem_wait(&context->empty);
pthread_mutex_lock(&(context->mutex));
context->buffer[i % BUFFER_SIZE] = 'a' + (rand() % 26);
float ranFloat = (float) rand() / RAND_MAX;
if (ranFloat < 0.5) sleep(0.2);
pthread_mutex_unlock(&(context->mutex));
sem_post(&context->full);
}
return NULL;
}
int main() {
char buffer[BUFFER_SIZE];
pthread_t reader, writer;
Context context;
srand(time(NULL));
int status = 0;
status = pthread_mutex_init(&context.mutex, NULL);
status = sem_init(&context.full,0,0);
status = sem_init(&context.empty,0, BUFFER_SIZE);
context.buffer = buffer;
status = pthread_create(&reader, NULL, Reader, &context);
status = pthread_create(&writer, NULL, Writer, &context);
pthread_join(reader,NULL); // This line seems to be necessary
pthread_join(writer,NULL); // This line seems to be necessary
pthread_exit(NULL);
return 0;
}
如果是这种情况,我该如何处理使用相同线程标识符创建大量相同线程(如以下代码)的情况?在那种情况下,我如何确保所有线程都在 main
退出之前完成?我真的必须保留一组 NUM_STUDENTS pthread_t
标识符才能执行此操作吗?我想我可以通过让学生线程发出信号量然后让 main
函数在该信号量上等待来做到这一点,但是真的没有更简单的方法吗?
int main()
{
pthread_t thread;
for (int i = 0; i < NUM_STUDENTS; i++)
pthread_create(&thread,NULL,Student,NULL); // Threads
// Make sure that all student threads have finished
exit(0);
}
最佳答案
pthread_exit()
是线程调用来终止自身执行的函数。对于您给出的情况,不能从您的主程序线程中调用它。
如您所知,pthread_join()
是等待来自 main()
的可连接线程完成的正确方法。
此外,您已经发现,您需要维护从 pthread_create()
返回的值以传递给 pthread_join()
。
这意味着如果您打算使用 pthread_join()
,则不能对您创建的所有线程使用相同的 pthread_t
变量。
相反,构建一个 pthread_t
数组,以便您拥有每个线程 ID 的副本。
关于c - C 中的 pthreads - pthread_exit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3330048/