Как начать потоки в plain C?

c multithreading

59945 просмотра

6 ответа

13338 Репутация автора

Я использовал fork () в C, чтобы начать другой процесс. Как начать новый поток?

Автор: Hanno Fietz Источник Размещён: 11.09.2008 03:04

Ответы (6)


7 плюса

42194 Репутация автора

pthreads - хорошее начало, посмотрите здесь

Автор: epatel Размещён: 11.09.2008 03:08

2 плюса

19317 Репутация автора

Проверьте библиотеку pthread (POSIX thread).

Автор: Jay Conrod Размещён: 11.09.2008 03:08

52 плюса

22500 Репутация автора

Решение

Поскольку вы упомянули fork (), я предполагаю, что вы используете Unix-подобную систему, и в этом случае потоки POSIX (обычно называемые pthreads) - это то, что вы хотите использовать.

В частности, pthread_create () - это функция, необходимая для создания нового потока. Его аргументы:

int  pthread_create(pthread_t  *  thread, pthread_attr_t * attr, void *
   (*start_routine)(void *), void * arg);

Первый аргумент - возвращаемый указатель на идентификатор потока. Второй аргумент - это аргументы потока, которые могут быть NULL, если вы не хотите запускать поток с определенным приоритетом. Третий аргумент - это функция, выполняемая потоком. Четвертый аргумент - это единственный аргумент, переданный функции потока, когда он выполняется.

Автор: Commodore Jaeger Размещён: 11.09.2008 03:09

12 плюса

21887 Репутация автора

AFAIK, ANSI C не определяет потоки, но существуют различные библиотеки.

Если вы работаете в Windows, обратитесь к msvcrt и используйте _beginthread или _beginthreadex.

Если вы работаете на других платформах, проверьте библиотеку pthreads (я уверен, что есть и другие).

Автор: Brannon Размещён: 11.09.2008 03:10

8 плюса

2018 Репутация автора

Темы не являются частью стандарта C, поэтому единственный способ использовать потоки - использовать некоторую библиотеку (например, потоки POSIX в Unix / Linux, _beginthread / _beginthreadex, если вы хотите использовать C-runtime из этого потока или просто CreateThread Win32 API)

Автор: botismarius Размещён: 11.09.2008 04:03

1 плюс

131100 Репутация автора

C11 потоки

Добавлено в glibc 2.28. Протестировано в Ubuntu 18.04 (glibc 2.27), скомпилировав glibc из источника: несколько библиотек glibc на одном хосте

Пример из: https://en.cppreference.com/w/c/language/atomic

#include <stdio.h>
#include <threads.h>
#include <stdatomic.h>

atomic_int acnt;
int cnt;

int f(void* thr_data)
{
    for(int n = 0; n < 1000; ++n) {
        ++cnt;
        ++acnt;
        // for this example, relaxed memory order is sufficient, e.g.
        // atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed);
    }
    return 0;
}

int main(void)
{
    thrd_t thr[10];
    for(int n = 0; n < 10; ++n)
        thrd_create(&thr[n], f, NULL);
    for(int n = 0; n < 10; ++n)
        thrd_join(thr[n], NULL);

    printf("The atomic counter is %u\n", acnt);
    printf("The non-atomic counter is %u\n", cnt);
}

Скомпилировать и запустить:

gcc -std=c11 main.c -pthread
./a.out

Возможный выход:

The atomic counter is 10000
The non-atomic counter is 8644

Неатомный счетчик, скорее всего, будет меньше, чем атомный, благодаря высокому доступу по потокам к неатомной переменной.

TODO: разобрать и посмотреть, что ++acnt;компилирует.

Потоки POSIX

#define _XOPEN_SOURCE 700
#include <assert.h>
#include <stdlib.h>
#include <pthread.h>

enum CONSTANTS {
    NUM_THREADS = 1000,
    NUM_ITERS = 1000
};

int global = 0;
int fail = 0;
pthread_mutex_t main_thread_mutex = PTHREAD_MUTEX_INITIALIZER;

void* main_thread(void *arg) {
    int i;
    for (i = 0; i < NUM_ITERS; ++i) {
        if (!fail)
            pthread_mutex_lock(&main_thread_mutex);
        global++;
        if (!fail)
            pthread_mutex_unlock(&main_thread_mutex);
    }
    return NULL;
}

int main(int argc, char **argv) {
    pthread_t threads[NUM_THREADS];
    int i;
    fail = argc > 1;
    for (i = 0; i < NUM_THREADS; ++i)
        pthread_create(&threads[i], NULL, main_thread, NULL);
    for (i = 0; i < NUM_THREADS; ++i)
        pthread_join(threads[i], NULL);
    assert(global == NUM_THREADS * NUM_ITERS);
    return EXIT_SUCCESS;
}

Скомпилировать и запустить:

gcc -std=c99 pthread_mutex.c -pthread
./a.out
./a.out 1

Первый запуск работает нормально, второй из-за отсутствия синхронизации.

Протестировано на Ubuntu 18.04. GitHub вверх по течению .

Автор: Ciro Santilli 新疆改造中心 六四事件 法轮功 Размещён: 22.09.2018 03:40
Вопросы из категории :
32x32