POSIX - семафоры, мьютексы, потоки C - PullRequest
0 голосов
/ 26 марта 2011

У меня есть это домашнее задание в школу - я выполнил его, отправил и получил 0%:] ... Поэтому я хотел бы спросить, верна ли моя идея.Например, если я хочу написать программу с потоками - мне нужно вызвать функцию 50 раз, и у меня есть 5 доступных потоков (и я должен использовать их все как можно больше).Не могли бы вы сказать мне, если я делаю что-то не так - наверное, потому, что printf говорит, что я использую только один поток?Я не слишком уверен в способе, которым я бы сделал эту вещь.

Заранее спасибо Nikolas Jíša

Вот мой исходный код:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

#define THREADS 5
#define CYCLES 50

sem_t sem1;
pthread_mutex_t m1, m2;
long int result = 0;
int thread_status[THREADS]; // status of threads, value -1 for working thread, other values for free threads

typedef struct Arg {
    long int number;
    int thread_ID; } ARG;

void * thrfunction ( void * arg ) {
    int number = (( ARG * ) arg)->number, thread_ID = (( ARG * ) arg)->thread_ID, i;
    thread_status[thread_ID] = -1;
    pthread_mutex_unlock ( & m1 );
    for ( i = 0; i < number; i ++ );
    pthread_mutex_lock ( & m2 );
    result = result + number;
    printf ( "Thread  %d  result = %ld\n", thread_ID, result );
    pthread_mutex_unlock ( & m2 );
    pthread_mutex_lock ( & m1 );
    thread_status[thread_ID] = thread_ID;
    sem_post ( & sem1 );
    pthread_mutex_unlock ( & m1 );
    return NULL; }

int main ( int argc, char * argv[] ) {
    pthread_t thr[THREADS];
    pthread_attr_t Attr; pthread_attr_init ( & Attr ); pthread_attr_setdetachstate ( & Attr, PTHREAD_CREATE_JOINABLE );
    pthread_mutex_init ( & m1, NULL ); pthread_mutex_init ( & m2, NULL );
    sem_init ( & sem1, 0, THREADS );

    int i, j;
    ARG * pom = ( ARG * ) malloc ( sizeof ( * pom ) );

    for ( i = 0; i < THREADS; i ++ )
        thread_status[i] = i;

    for ( i = 0; i < CYCLES; i ++ ) {
        pom->number = rand () % 100000 * 10000;
        sem_wait ( & sem1 );
        pthread_mutex_lock ( & m1 );
        for ( j = 0 ; j == -1; j ++ );
            pthread_create ( & thr[j], & Attr, thrfunction, ( void * ) pom ); }
    free ( pom );
    pthread_attr_destroy ( & Attr ); pthread_mutex_destroy ( & m1 ); pthread_mutex_destroy ( & m2 ); sem_destroy ( & sem1 );
    for ( i = 0; i < THREADS; i ++ )
        pthread_join ( thr[i], NULL );
    return 0;}

1 Ответ

2 голосов
/ 26 марта 2011

Первая проблема, которую я вижу, заключается в том, что вы используете блокировки слишком часто .

Потоки гораздо менее эффективны, чем последовательное программирование, если все, что ваша программа делает, это берет блокировки.Замки стоят времени, чтобы взять и отпустить.Это время отнимается у той работы, которую должна выполнять ваша программа.

Вторая проблема, которую я вижу, заключается в том, что ваш for цикл в thrfunction ничего не делает.Я считаю от 0 до числа?Это все, что он делает?

Третья проблема, которую я вижу, это то, что вы звоните free(pom) и вы вызываете pthread_mutex_destroy после создания всех потоков. ПЛОХО! Темы все еще используют его!У вас нет гарантии, что потоки даже начали работать в этот момент.Ваша операционная система может занять несколько секунд или даже минут (если она была нехватка ОЗУ и подкачки на диск), чтобы запустить все те потоки, которые вы создали.каждая «критическая секция», части между замками, на карточках, или использовать что-либо подвижное, чтобы представить эти части.Сделайте столбец из этих карт или кусочки для каждой нити.Эти фрагменты могут перемещаться в любом месте вверх или вниз по временной шкале, если блокировка, соединение, семафоры или что-либо еще не мешают этому.Если вы хотите получить действительно техническую информацию, оптимизация компилятора и выполнение процессора вне очереди могут даже изменить порядок выполнения частей в определенных пределах.

Некоторые программы (не ваша) могут выглядеть следующим образом (и смотреть накак поток замедляется до единой скорости при блокировке в шаге 7):

                0 <- parent process spawns threads
                1 <- parent process calls join to wait for thread in first column.
 2   2   2   
 3       3   
 4   3   4   
 5       5   2 
 6       6   3
             4
             5
             6
 7   4   7   7   <-- step 7 waits for lock
     5   8
     6   9
     7  10
        11       <- step 11 releases lock
 8
 9
10
11
     8
     9
    10
    11
             8
             9
            10
            11
12  12  12  12
13  13  13  13
14  14  14  14 <- step 14 each thread returns.
                15 <- parent process wait on thread 1 succeeds.
                16 <- wait for thread 2
                17 <- wait for thread 3
                18 <- wait for thread 4
                19 <- parent now cleans up thread data, lock data.
                20 <- parent exits.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...