Тема создана, но не работает соответственно - PullRequest
0 голосов
/ 21 апреля 2019

У меня возникла проблема с кодом, который я пишу, но я действительно не могу понять, чем он вызван, так что помощь была бы очень признательна.
Случай прост
-> указание количества потоков в качестве аргумента из командной строки
-> создание N потоков с параметром
-> каждый поток говорит привет, его параметр и выход
Итак, вот мой код:

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

void* client_func(void *arg) {
    int myid = *((int *) arg);
    printf("hello!\n my id is %d\n",myid);
    return NULL;
}

int main(int argc, char *argv[] ){
    int i,j = 0;
    int N_cust = atoi(argv[1]);

    //creation of client threads
    pthread_t tid[N_cust];
    int err;

    for (i = 0; i < N_cust; i++){
        int *id = malloc(sizeof(*id));
        err = pthread_create(&tid[i], NULL, &client_func,(void *) id);
        if(err !=0){
            perror("pthread_create() error");
            exit(1);
       }
       else{
           printf("\n Thread created successfully\n");
       }
    }

    return 0;
}

Я ждал, чтобы в результате получить «привет» сообщения с идентификатором потока, но вместо этого я получил:

$ ./proj1 3 5

Тема успешно создана
Тема успешно создана
Тема успешно создана

Я новичок в потоках, но из моего понимания поток не выполняется вообще.Любая помощь в том, что я делаю не так?Спасибо

1 Ответ

1 голос
/ 21 апреля 2019

Как я отмечал в комментарии , у вас есть ряд проблем в вашем коде:

  • Вы выделяете место для указателя id, на который указывает, но выникогда не устанавливайте для него какое-либо известное значение.
  • Ваша функция потока также забывает освободить выделенную ей память.
  • Вероятно, ваша основная программа должна также дождаться завершения дочерних потоков с pthread_join() до его выхода (через return 0;).

Вызов exit() - даже косвенно путем возврата из main() - означает, что процесс (и все потоки в нем) немедленно завершаются.Вместо этого вы могли бы использовать pthread_exit(0); в main() вместо return 0;, и вы могли бы заставить свои потоки работать до конца.

Вот два варианта вашего кода с исправленными этими проблемами.Вариант 1 (pthr41.c) имеет выход основного потока с pthread_exit(0);.Вариант 2 (pthr43.c) имеет основной поток использования pthread_join().Добавлена ​​возможность обнаружения ошибок.

pthr41.c

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

static void *client_func(void *arg)
{
    int myid = *((int *)arg);
    printf("\nhello! my id is %d\n", myid);
    free(arg);
    return NULL;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s numthreads\n", argv[0]);
        return 1;
    }
    int N_cust = atoi(argv[1]);
    if (N_cust <= 0 || N_cust > 1000)
    {
        fprintf(stderr, "%s: number of threads %s out of range 1..1000\n", argv[0], argv[1]);
        return 1;
    }

    // creation of client threads
    pthread_t tid[N_cust];

    for (int i = 0; i < N_cust; i++)
    {
        int *id = malloc(sizeof(*id));
        *id = i + 1;
        int err = pthread_create(&tid[i], NULL, client_func, id);
        if (err != 0)
        {
            perror("pthread_create() error");
            exit(1);
        }
        else
        {
            printf("\nThread %d created successfully\n", i + 1);
        }
    }

    printf("\nMain thread exits\n");
    pthread_exit(0);
    //return 0;
}

Пример вывода

Потребовалось несколько прогонов, прежде чем я получил этот вывод, но это показываетнить 4 чистовая после основной нити:

$ pthr41 4

Thread 1 created successfully

Thread 2 created successfully

hello! my id is 1

hello! my id is 2

hello! my id is 3

Thread 3 created successfully

Thread 4 created successfully

Main thread exits

hello! my id is 4
$

pthr43.c

#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static void *client_func(void *arg)
{
    int myid = *((int *)arg);
    printf("\nhello! my id is %d\n", myid);
    free(arg);
    return NULL;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s numthreads\n", argv[0]);
        return 1;
    }
    int N_cust = atoi(argv[1]);
    if (N_cust <= 0 || N_cust > 1000)
    {
        fprintf(stderr, "%s: number of threads %s out of range 1..1000\n", argv[0], argv[1]);
        return 1;
    }

    // creation of client threads
    pthread_t tid[N_cust];

    for (int i = 0; i < N_cust; i++)
    {
        int *id = malloc(sizeof(*id));
        *id = i + 1;
        int err = pthread_create(&tid[i], NULL, client_func, id);
        if (err != 0)
        {
            perror("pthread_create() error");
            exit(1);
        }
        else
        {
            printf("\nThread %d created successfully\n", i + 1);
        }
    }

    for (int i = 0; i < N_cust; i++)
    {
        void *vp;
        int err = pthread_join(tid[i], &vp);
        if (err != 0)
        {
            fprintf(stderr, "%s: error %d (%s) from joining thread %d\n",
                    argv[0], err, strerror(err), i + 1);
        }
        else
            assert(vp == NULL);
    }
    printf("All threads complete\n");

    //pthread_exit(0);
    return 0;
}

Пример вывода

$ pthr43 4

Thread 1 created successfully

hello! my id is 1

hello! my id is 2

Thread 2 created successfully

Thread 3 created successfully

hello! my id is 3

Thread 4 created successfully

hello! my id is 4
All threads complete
$
...