Рубрики

Многопоточность в C

Что такое тема?
Поток — это отдельный поток последовательности внутри процесса. Поскольку потоки имеют некоторые свойства процессов, их иногда называют.

Каковы различия между процессом и потоком?
Потоки не являются независимыми друг от друга, как процессы, в результате потоки делятся с другими потоками своими разделами кода, данными и ресурсами ОС, такими как открытые файлы и сигналы. Но, как и процесс, поток имеет свой собственный программный счетчик (ПК), набор регистров и пространство стека.

Почему многопоточность?
Потоки — это популярный способ улучшить приложение с помощью параллелизма. Например, в браузере несколько вкладок могут быть разными потоками. MS word использует несколько потоков, один поток для форматирования текста, другой поток для обработки ввода и т. Д.
Потоки работают быстрее, чем процессы по следующим причинам:
1) Создание темы намного быстрее.
2) Переключение контекста между потоками происходит намного быстрее.
3) темы могут быть легко прекращены
4) Связь между потоками быстрее.

См. Http://www.personal.kent.edu/~rmuhamma/OpSystems/Myos/threads.htm для получения более подробной информации.

Можем ли мы написать многопоточные программы на C?
В отличие от Java, многопоточность не поддерживается стандартом языка. POSIX Threads (или Pthreads) — это стандарт POSIX для потоков. Реализация pthread доступна с компилятором gcc.

Простая C-программа для демонстрации использования базовых функций pthread
Обратите внимание, что приведенная ниже программа может компилироваться только с компиляторами C с библиотекой pthread.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>  //Header file for sleep(). man 3 sleep for details.
#include <pthread.h>

  
// Обычная функция C, которая выполняется как поток
// когда его имя указано в pthread_create ()

void *myThreadFun(void *vargp)

{

    sleep(1);

    printf("Printing GeeksQuiz from Thread \n");

    return NULL;

}

   

int main()

{

    pthread_t thread_id;

    printf("Before Thread\n");

    pthread_create(&thread_id, NULL, myThreadFun, NULL);

    pthread_join(thread_id, NULL);

    printf("After Thread\n");

    exit(0);

}

В main () мы объявляем переменную с именем thread_id, которая имеет тип pthread_t, который является целым числом, используемым для идентификации потока в системе. После объявления thread_id мы вызываем функцию pthread_create () для создания потока.
pthread_create () принимает 4 аргумента.
Первый аргумент — это указатель на thread_id, который устанавливается этой функцией.
Второй аргумент определяет атрибуты. Если значение равно NULL, то должны использоваться атрибуты по умолчанию.
Третий аргумент — это имя функции, которая должна быть выполнена для создаваемого потока.
Четвертый аргумент используется для передачи аргументов функции, myThreadFun.
Функция pthread_join () для потоков является эквивалентом wait () для процессов. Вызов pthread_join блокирует вызывающий поток, пока поток с идентификатором, равным первому аргументу, не завершится.

Как скомпилировать вышеуказанную программу?
Чтобы скомпилировать многопоточную программу с использованием gcc, нам нужно связать ее с библиотекой pthreads. Ниже приведена команда, используемая для компиляции программы.

gfg@ubuntu:~/$ gcc multithread.c -lpthread
gfg@ubuntu:~/$ ./a.out
Before Thread
Printing GeeksQuiz from Thread 
After Thread
gfg@ubuntu:~/$ 

AC программа для отображения нескольких потоков с глобальными и статическими переменными
Как упомянуто выше, все потоки разделяют сегмент данных. Глобальные и статические переменные хранятся в сегменте данных. Таким образом, они являются общими для всех потоков. Следующий пример программы демонстрирует то же самое.

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

  
// Давайте создадим глобальную переменную, чтобы изменить ее в потоках

int g = 0;

  
// Функция, выполняемая всеми потоками

void *myThreadFun(void *vargp)

{

    // Сохраняем аргумент значения, переданный в этот поток

    int *myid = (int *)vargp;

  

    // Давайте создадим статическую переменную для наблюдения за ее изменениями

    static int s = 0;

  

    // Изменить статические и глобальные переменные

    ++s; ++g;

  

    // Распечатать аргумент, статические и глобальные переменные

    printf("Thread ID: %d, Static: %d, Global: %d\n", *myid, ++s, ++g);

}

  

int main()

{

    int i;

    pthread_t tid;

  

    // Давайте создадим три потока

    for (i = 0; i < 3; i++)

        pthread_create(&tid, NULL, myThreadFun, (void *)&tid);

  

    pthread_exit(NULL);

    return 0;

}

gfg@ubuntu:~/$ gcc multithread.c -lpthread
gfg@ubuntu:~/$ ./a.out
Thread ID: 3, Static: 2, Global: 2
Thread ID: 3, Static: 4, Global: 4
Thread ID: 3, Static: 6, Global: 6
gfg@ubuntu:~/$ 

Обратите внимание, что выше приведен простой пример, демонстрирующий работу потоков. Доступ к глобальной переменной в потоке, как правило, плохая идея. Что, если поток 2 имеет приоритет над потоком 1, а поток 1 должен изменить переменную. На практике, если требуется доступ к глобальной переменной несколькими потоками, доступ к ним должен осуществляться с помощью мьютекса.

Ссылки:
http://www.csc.villanova.edu/~mdamian/threads/posixthreads.html
Компьютерные системы: программист

Эта статья пополняемая Рахул Джейна. Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

Многопоточность в C

0.00 (0%) 0 votes