【问题标题】:How can I set a thread to end only when another threads are running?如何将一个线程设置为仅在另一个线程运行时才结束?
【发布时间】:2020-05-04 18:47:53
【问题描述】:

我创建了 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);
}

但它不起作用。有什么建议吗?

【问题讨论】:

  • 许多线程在等待而只有少数处于活动状态,这听起来就像您想要一个带有工作队列线程池。然后你可以按照你想要的顺序和数量将工作分派给等待线程。您可能想对这些术语进行一些研究。

标签: c linux multithreading synchronization


【解决方案1】:
if(*thread_nr == 13) {
    pthread_mutex_lock(&mutex);
    pthread_cond_wait(&end13, &mutex);
    pthread_mutex_unlock(&mutex); 
}

条件变量是无状态的,需要您使用它们关联的互斥锁来保护状态。互斥体在这里不保护任何东西,因此您无需等待 任何东西。你永远不会让条件变量以这种方式正常工作。

您的代码很可能会失败,因为即使没有任何等待,该线程仍在调用pthread_cond_wait,因此它会一直等待。您获取了互斥锁来检查共享状态,但是您没有这样做。

您要么不使用条件变量,要么了解它们的工作原理。特别是,您必须了解从根本上说,它们提供了一种原子的“解锁并等待”操作,以避免出现竞争条件,即您等待已经发生的事情。

阅读this question 及其答案可能会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 2022-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多