Я хочу написать программу, которая может останавливать (зависать) все другие потоки pthread без основного потока, я использую pthread_kill для отправки сигнала целевому потоку для вызова его обработчика сигнала, который может блокировать себя. Но я застрял. Вот код ниже:

#include <iostream>
#include <signal.h> 
#include <pthread.h>
#include <unistd.h>
#include <cassert>

using namespace std;

pthread_mutex_t _mutex;
pthread_cond_t cond;

void cur_thread_wait(int sig)
{
    cout << pthread_self() << endl;

//  pthread_mutex_lock(&_mutex);
    pthread_cond_wait(&cond, &_mutex);  
//  pthread_mutex_unlock(&_mutex);
}

void signal_all()
{
    pthread_cond_broadcast(&cond);
}

void *print(void *)
{
    pthread_detach(pthread_self());
    for (int i = 0; i < 100; i ++) {
        cout << dec << i << endl;
    }
    return nullptr;
}


int main(int argc, char *argv[]) 
{
    pthread_mutex_init(&_mutex, nullptr);
    pthread_cond_init(&cond, nullptr);

    signal(SIGUSR1, cur_thread_wait);

    pthread_t pid1, pid2, pid3;
    pthread_create(&pid1, nullptr, print, nullptr);
    pthread_create(&pid2, nullptr, print, nullptr);
    pthread_create(&pid3, nullptr, print, nullptr);

//  usleep(400);

    pthread_kill(pid1, SIGUSR1);
    pthread_kill(pid2, SIGUSR1);
    pthread_kill(pid3, SIGUSR1);

    signal_all();


    pthread_exit(nullptr);
}

На самом деле, я думаю, что действительно нет необходимости создавать mutex (это правда?) ... Я новичок в программировании под Linux. Как я могу исправить эту проблему? Спасибо.

0
wind2412 20 Дек 2017 в 07:43

1 ответ

Лучший ответ

Вам действительно необходимо заблокировать мьютекс перед вызовом pthread_cond_wait; он ожидает, что он будет заблокирован, он разблокирует его, ожидает подтверждения переменной условия, а затем повторно блокирует его, прежде чем вернуться к вам.

От pthread_cond_wait(3p):

int pthread_cond_wait(pthread_cond_t *restrict cond,
    pthread_mutex_t *restrict mutex);

Функции pthread_cond_timedwait() и pthread_cond_wait() должны блокироваться по переменной условия. Приложение должно гарантировать, что эти функции вызываются с мьютексом , заблокированным вызывающим потоком; в противном случае возникает ошибка (для PTHREAD_MUTEX_ERRORCHECK и надежных мьютексов) или неопределенное поведение (для других мьютексов).

1
Ben Stern 20 Дек 2017 в 08:17