Как сделать паузу в любое время, которое я хочу? - PullRequest
4 голосов
/ 22 февраля 2012

недавно я решил портировать ucos-ii на Ubuntu PC.

Как мы знаем, невозможно смоделировать «процесс» в ucos-ii, просто добавив флаг в цикле «while» в функцию обратного вызова pthread, чтобы выполнить паузу и возобновление (как решение ниже). Потому что «процесс» в ucos-ii может быть приостановлен или возобновлен в любое время!

Как спать или приостановить PThread в c в Linux

Я нашел одно решение на веб-сайте ниже, но оно не может быть построено, потому что оно устарело. Он использует процесс в Linux для имитации задачи (действует как процесс в нашем Linux) в ucos-ii.

http://www2.hs -esslingen.de / ~ zimmerma / Программное обеспечение / index_uk.html

Если pthread может действовать как процесс, который может быть приостановлен и возобновлен в любое время, скажите, пожалуйста, о некоторых связанных функциях, я сам это выясню. Если это невозможно, я думаю, что я должен сосредоточиться на старом решении. Большое спасибо.

Ответы [ 3 ]

4 голосов
/ 16 августа 2014

Сборщик мусора Modula-3 должен приостановить pthreads в произвольное время, а не только тогда, когда они ожидают переменную условия или мьютекс.Это делается путем регистрации обработчика сигнала (Unix), который приостанавливает поток, а затем с помощью pthread_kill отправляет сигнал целевому потоку.Я думаю, что это работает (это было надежно для других, но я решаю проблему с этим прямо сейчас ...) Это немного глупо, хотя ....

Google для ThreadPThread.m3 и посмотрите наподпрограммы "StopWorld" и "StartWorld".Сам обработчик находится в ThreadPThreadC.c.

2 голосов
/ 23 февраля 2012

Если остановка в определенных точках с условной переменной недостаточна, то вы не можете сделать это с помощью pthreads. Интерфейс pthread не включает в себя функции приостановки / возобновления.

См., Например, ответ E.4 здесь :

Стандарт POSIX не предусматривает механизма, с помощью которого поток A может приостановить выполнение другого потока B без сотрудничества с B. Единственный способ реализовать механизм приостановки / перезапуска - это периодически проверять B некоторую глобальную переменную для приостановки. запросить, а затем приостановить работу над условной переменной, о которой другой поток может сообщить позже для перезапуска B.

В этом ответе на часто задаваемые вопросы описывается пара нестандартных способов сделать это, один в Solaris и один в LinuxThreads (который сейчас устарел; не путайте его с текущими потоками в Linux); ни один из них не применим к вашей ситуации.

0 голосов
/ 15 ноября 2013

Вот пример функции потока внутри класса с функцией паузы / возобновления ...

class SomeClass
{
public:
    // ... construction/destruction

    void Resume();
    void Pause();
    void Stop();

private:
    static void* ThreadFunc(void* pParam);

    pthread_t thread;
    pthread_mutex_t mutex;
    pthread_cond_t cond_var;
    int command;
};

SomeClass::SomeClass()
{
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond_var, NULL);

    // create thread in suspended state..
    command = 0;
    pthread_create(&thread, NULL, ThreadFunc, this);
}

SomeClass::~SomeClass()
{
    // we should stop the thread and exit ThreadFunc before calling of blocking pthread_join function
    // also it prevents the mutex staying locked..
    Stop();
    pthread_join(thread, NULL);

    pthread_cond_destroy(&cond_var);
    pthread_mutex_destroy(&mutex);
}

void* SomeClass::ThreadFunc(void* pParam)
{
    SomeClass* pThis = (SomeClass*)pParam;
    timespec time_ns = {0, 50*1000*1000};   // 50 milliseconds

    while(1)
    {
        pthread_mutex_lock(&pThis->mutex);

        if (pThis->command == 2) // command to stop thread..
        {
            // be sure to unlock mutex before exit..
            pthread_mutex_unlock(&pThis->mutex);
            return NULL;
        }
        else if (pThis->command == 0) // command to pause thread..
        {
            pthread_cond_wait(&pThis->cond_var, &pThis->mutex);
            // dont forget to unlock the mutex..
            pthread_mutex_unlock(&pThis->mutex);
            continue;
        }

        if (pThis->command == 1) // command to run..
        {
            // normal runing process..
            fprintf(stderr, "*");
        }

        pthread_mutex_unlock(&pThis->mutex);

        // it's important to give main thread few time after unlock 'this'
        pthread_yield();
        // ... or...
        //nanosleep(&time_ns, NULL);
    }
    pthread_exit(NULL);
}

void SomeClass::Stop()
{
    pthread_mutex_lock(&mutex);
    command = 2;
    pthread_cond_signal(&cond_var);
    pthread_mutex_unlock(&mutex);
}

void SomeClass::Pause()
{
    pthread_mutex_lock(&mutex);
    command = 0;
    // in pause command we dont need to signal cond_var because we not in wait state now..
    pthread_mutex_unlock(&mutex);
}

void SomeClass::Resume()
{
    pthread_mutex_lock(&mutex);
    command = 1;
    pthread_cond_signal(&cond_var);
    pthread_mutex_unlock(&mutex);
}
...