PThread Вопрос - PullRequest
       13

PThread Вопрос

0 голосов
/ 01 июля 2011

Я пытаюсь сделать небольшой пример. Я хочу иметь переменную, и каждый поток пытается увеличить его, а затем остановить, как только он достигнет определенной точки. Всякий раз, когда переменная заблокирована, я хочу, чтобы какое-то сообщение было распечатано как «поток x пытается заблокировать, но не может», так что я ЗНАЮ, что он работает правильно. Это мои первые дневные темы по кодированию, поэтому не стесняйтесь указывать на что-нибудь ненужное в коде здесь -

#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

#define NUM_THREADS 2
pthread_t threads[NUM_THREADS];
pthread_mutex_t mutexsum;

int NUMBER = 0;
void* increaseByHundred(void* threadid) {

    if(pthread_mutex_lock(&mutexsum))
        cout<<"\nTHREAD "<<(int)threadid<<" TRYING TO LOCK BUT CANNOT";

    else {
        for(int i=0;i<100;i++) {
            NUMBER++;
            cout<<"\nNUMBER: "<<NUMBER;
        }
        pthread_mutex_unlock(&mutexsum);
        pthread_exit((void*)0);
    }
}


int main(int argc, char** argv) {

    int rc;
    int rc1;
    void* status;

    pthread_attr_t attr;

    pthread_mutex_init(&mutexsum, NULL);
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    rc = pthread_create(&threads[0], &attr, increaseByHundred, (void*)0);
    rc1 = pthread_create(&threads[1], &attr, increaseByHundred, (void*)1);

    pthread_attr_destroy(&attr);

    while(NUMBER < 400)
        pthread_join(threads[0], &status);


    pthread_mutex_destroy(&mutexsum);
    pthread_exit(NULL);

}

Я читал учебник, найденный здесь https://computing.llnl.gov/tutorials...reatingThreads и попытался адаптировать свой пример мьютекса к этой идее. Код увеличивает его до 199, а затем останавливается. Я предполагаю, потому что потоки делают свою рутину только один раз. Есть ли способ заставить их просто выполнять свои обычные дела, кроме тех случаев, когда вы их создаете, чтобы я мог сказать

пока что-то выполняй свою рутину

У меня есть pthread_join там только потому, что он был похож на то, что было в их уроке. Я действительно даже не понимаю, что это ясно, хотя. Я почти уверен, что проблема в линии ... Я просто не знаю, как это исправить. Любая помощь приветствуется.

Ответы [ 3 ]

2 голосов
/ 01 июля 2011

Всякий раз, когда переменная заблокирована, я хочу, чтобы какое-то сообщение выводилось наподобие «поток x пытается заблокировать, но не может», чтобы я ЗНАЛ, что он работает правильно.Почему ты этого хочешь?Вы только узнаете о темах.Изучите основы в первую очередь.Не углубляйтесь в глубокий конец в pthread_mutex_trylock или мьютексы, настроенные для проверки ошибок.Вам нужно научиться ходить, прежде чем вы научитесь бегать.

Основы включают инициализацию мьютекса с настройками по умолчанию и использование pthread_mutex_lock для захвата блокировки.При настройках по умолчанию pthread_mutex_lock вернет ненулевое значение только в случае больших и больших проблем.Здесь могут возникнуть только две проблемы: тупик и неверный указатель мьютекса.Там нет восстановления ни от одного;единственное реальное решение - это исправить код.Единственное, что вы можете здесь сделать, это создать исключение, которое вы не перехватываете, вызвать exit () или abort () и т. Д.

То, что какой-то другой поток заблокировал мьютекс, не является большой проблемой.,Это не проблема вообще.pthread_mutex_lock будет блокироваться (например, идти спать), пока блокировка не станет доступной.Нулевой возврат от pthread_mutex_lock означает, что вызывающий поток теперь имеет блокировку.Просто убедитесь, что вы сняли блокировку, когда закончили работать с защищенной памятью.

Редактировать
Вот предложение, которое позволит вам увидеть, что механизм потоков работает так, как объявлено.

  1. При вводе в increaseByHundred распечатать сообщение с отметкой времени, указывающее на вход в функцию.Вы, вероятно, хотите использовать C printf здесь, а не C ++ I / O.printf() и связанные функции являются поточно-ориентированными.C ++ 2003 В / В нет.
  2. После успешного возврата из pthread_mutex_lock напечатайте еще одно сообщение с меткой времени, указывающее на успешную блокировку.
  3. sleep() на несколько секунд, а затем напечатайтееще одно сообщение с отметкой времени до вызова pthread_mutex_unlock().
  4. Сделайте то же самое перед вызовом pthread_exit().

Последний комментарий: вы проверяете ошибку, возвращаемую из pthread_mutex_lock.Для полноты и потому, что каждый хороший программист параноик, когда все выходят, вы должны также проверить статус возврата с pthread_mutex_unlock.

Как насчет pthread_exit?У него нет статуса возврата.Вы могли бы напечатать некоторое сообщение после вызова pthread_exit, но вы достигнете этого утверждения только в том случае, если вы используете несовместимую версию библиотеки потоков.Функция pthread_exit() не может вернуться к вызывающей функции.Период.Беспокойство по поводу того, что произойдет, когда pthreads_exit() вернется, - упражнение в шляпе из фольгиВ то время как хорошие программисты должны быть параноиками, они не должны быть параноиками-шизофрениками.

0 голосов
/ 01 июля 2011

pthread_mutex_lock обычно просто блокируется, пока не получит блокировку, и поэтому строка cout<<"\nTHREAD "<<(int)threadid<<" TRYING TO LOCK BUT CANNOT"; не запускается.У вас также есть проблемы в

while(NUMBER < 400)
     pthread_join(threads[0], &status);

, потому что у вас просто 2 потока и число никогда не достигнет 400. Вы также хотите присоединиться к потоку [0] на первой итерации, а затем к потоку [1] ...

0 голосов
/ 01 июля 2011

pthread_mutex_trylock ():

if (pthread_mutex_trylock(&mutex) == EBUSY) {
    cout << "OMG NO WAY ITS LOCKED" << endl;
}

Стоит также отметить, что если мьютекс не заблокирован, он сможет получить блокировку и затем будет вести себя как обычный pthread_mutex_lock().

...