如何设置一个线程仅在另一个线程 运行 时才结束?
How can I set a thread to end only when another threads are running?
我同时创建了 44 个线程,其中只有 6 个线程 运行,我希望线程 13 仅在信号量值为 0 时结束(另外 5 个线程为 运行)。我尝试使用这样的条件变量:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <fcntl.h>
int curr_threads = 0;
int sem_id;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t end13 = PTHREAD_COND_INITIALIZER;
void P(int sem_id){
struct sembuf semaphore_op = {0, -1, 0};
semop(sem_id, &semaphore_op, 1);
}
void V(int sem_id){
struct sembuf semaphore_op = {0, 1, 0};
semop(sem_id, &semaphore_op, 1);
}
void* thread_func(void* arg) {
P(sem_id);
pthread_mutex_lock(&mutex);
curr_threads++;
if(curr_threads == 6) pthread_cond_signal(&end13);
pthread_mutex_unlock(&mutex);
int* thread_nr = (int*) arg;
if(*thread_nr == 13) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&end13, &mutex);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex);
curr_threads--;
pthread_mutex_unlock(&mutex);
V(sem_id);
return (void*) 0;
}
int main(int argc, char** argv) {
sem_id = semget(1234, 1, IPC_CREAT | 0600);
pthread_t threads[44];
semctl(sem_id, 0, SETVAL, 6);
int aux[44];
for(int i = 0; i < 44; i++) {
aux[i] = i + 1;
}
for(int i = 0; i < 44; i++) {
pthread_create(&threads[i], NULL, thread_func, &aux[i]);
}
for(int i = 0; i < 44; i++) {
pthread_join(threads[i], NULL);
}
exit(0);
}
但它不起作用。有什么建议吗?
if(*thread_nr == 13) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&end13, &mutex);
pthread_mutex_unlock(&mutex);
}
条件变量是无状态的,需要您使用其关联的互斥锁来保护状态。互斥锁在这里不保护任何东西,所以你不用等待 for 任何东西。您将永远无法通过这种方式使条件变量正常工作。
您的代码很可能会失败,因为此线程正在调用 pthread_cond_wait
,即使没有什么可等待的,因此它会永远等待。您获取了互斥锁来检查共享状态,但后来您没有这样做。
您要么不使用条件变量,要么了解它们的工作原理。特别是,您 必须 了解它们从根本上提供了一个原子 "unlock and wait" 操作来避免您等待已经发生的事情的竞争条件。
阅读 及其答案可能会有帮助。
我同时创建了 44 个线程,其中只有 6 个线程 运行,我希望线程 13 仅在信号量值为 0 时结束(另外 5 个线程为 运行)。我尝试使用这样的条件变量:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <fcntl.h>
int curr_threads = 0;
int sem_id;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t end13 = PTHREAD_COND_INITIALIZER;
void P(int sem_id){
struct sembuf semaphore_op = {0, -1, 0};
semop(sem_id, &semaphore_op, 1);
}
void V(int sem_id){
struct sembuf semaphore_op = {0, 1, 0};
semop(sem_id, &semaphore_op, 1);
}
void* thread_func(void* arg) {
P(sem_id);
pthread_mutex_lock(&mutex);
curr_threads++;
if(curr_threads == 6) pthread_cond_signal(&end13);
pthread_mutex_unlock(&mutex);
int* thread_nr = (int*) arg;
if(*thread_nr == 13) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&end13, &mutex);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex);
curr_threads--;
pthread_mutex_unlock(&mutex);
V(sem_id);
return (void*) 0;
}
int main(int argc, char** argv) {
sem_id = semget(1234, 1, IPC_CREAT | 0600);
pthread_t threads[44];
semctl(sem_id, 0, SETVAL, 6);
int aux[44];
for(int i = 0; i < 44; i++) {
aux[i] = i + 1;
}
for(int i = 0; i < 44; i++) {
pthread_create(&threads[i], NULL, thread_func, &aux[i]);
}
for(int i = 0; i < 44; i++) {
pthread_join(threads[i], NULL);
}
exit(0);
}
但它不起作用。有什么建议吗?
if(*thread_nr == 13) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&end13, &mutex);
pthread_mutex_unlock(&mutex);
}
条件变量是无状态的,需要您使用其关联的互斥锁来保护状态。互斥锁在这里不保护任何东西,所以你不用等待 for 任何东西。您将永远无法通过这种方式使条件变量正常工作。
您的代码很可能会失败,因为此线程正在调用 pthread_cond_wait
,即使没有什么可等待的,因此它会永远等待。您获取了互斥锁来检查共享状态,但后来您没有这样做。
您要么不使用条件变量,要么了解它们的工作原理。特别是,您 必须 了解它们从根本上提供了一个原子 "unlock and wait" 操作来避免您等待已经发生的事情的竞争条件。
阅读