Читатели като вас помагат в подкрепа на MUO. Когато правите покупка чрез връзки на нашия сайт, ние може да спечелим комисионна за партньор. Прочетете още.

В Linux можете да създавате и управлявате нишки в C/C++, като използвате библиотеката POSIX нишка (pthread). За разлика от други операционни системи, в Linux има малка разлика между нишка и процес. Ето защо Linux често нарича своите нишки леки процеси.

С помощта на библиотеката pthread можете да създавате нишки, да ги изчаквате да прекратят и да ги прекратявате изрично.

Историята на използването на нишки в Linux

Преди Linux версия 2.6 основната реализация на нишката беше LinuxThreads. Това внедряване имаше значителни ограничения по отношение на производителността и операциите за синхронизация. Ограничение за максималния брой нишки, които могат да се изпълняват, ги ограничава до 1000-те.

През 2003 г. екип, ръководен от разработчици от IBM и RedHat, успя да създаде Вградена библиотека с нишки POSIX (NPTL) наличен проект. Той беше представен за първи път в RedHat Enterprise версия 3 за разрешаване на проблеми с производителността на Java Virtual Machine на Linux. Днес библиотеката GNU C съдържа реализации и на двата механизма за нишки.

instagram viewer

Нито едно от тях не е имплементация на зелени нишки, които виртуална машина би управлявала и изпълнявала в чисто потребителски режим. Когато използвате библиотеката pthread, ядрото създава нишка при всяко стартиране на програма.

Можете да намерите конкретна информация за нишки за всеки работещ процес във файловете под /proc//task. Това е стандартното местоположение за информация за процеса под стандартът procfs Linux. За приложения с една нишка ще изглежда, че има запис на задача със същата стойност като PID в тази директория.

Работна логика на нишките

Нишките са като процеси, изпълнявани в момента в операционната система. В еднопроцесорни системи (напр. микроконтролери) ядрото на операционната система симулира нишки. Това позволява транзакциите да се изпълняват едновременно чрез нарязване.

Едноядрената операционна система наистина може да изпълнява само един процес наведнъж. Въпреки това, в многоядрени или многопроцесорни системи, тези процеси могат да се изпълняват едновременно.

Създаване на нишка в C

Можете да използвате pthread_create функция за създаване на нова нишка. The pthread.h заглавният файл включва неговата дефиниция на подпис заедно с други функции, свързани с нишката. Нишките използват същото адресно пространство и файлови дескриптори като основната програма.

Библиотеката pthread също така включва необходимата поддръжка за mutex и условни операции, необходими за операции за синхронизация.

Когато използвате функциите на библиотеката pthread, трябва да сте сигурни, че компилаторът свързва pthread библиотека във вашия изпълним файл. Ако е необходимо, можете да инструктирате компилатора да се свърже към библиотеката с помощта на опция:

gcc -o тест test_thread.c -lpthread

Функцията pthread_create има следния подпис:

вътрpthread_create(pthread_t *нишка, констpthread_attr_t *attr, невалиден *(*start_routine)(невалиден *), невалиден *арг)

Връща 0, ако процедурата е успешна. Ако има проблем, той връща ненулев код за грешка. В горния подпис на функцията:

  • The резба параметърът е от тип pthread_t. Създадената нишка винаги ще бъде достъпна с тази препратка.
  • The атрибут параметър ви позволява да зададете персонализирано поведение. Можете да използвате поредица от специфични за нишката функции, започвайки с pthread_attr_ за да зададете тази стойност. Възможните персонализации са правилата за планиране, размера на стека и правилата за отделяне.
  • стартова_рутина указва функцията, която нишката ще изпълнява.
  • арг представлява обща структура от данни, предадена на функцията от нишката.

Ето едно примерно приложение:

#включват
#включват
#включват
#включват

невалиден *работник(невалиден *данни)
{
въглен *име = (въглен*)данни;

за (вътр аз = 0; аз < 120; i++)
{
спим(50000);
printf("Здравей от име на нишка = %s\n", име);
}

printf("Нишка %s готова!\n", име);
връщанеНУЛА;
}

вътросновен(невалиден)
{
pthread_t th1, th2;
pthread_create(&th1, НУЛА, работник, "X");
pthread_create(&th2, НУЛА, работник, "Y");
сън(5);
printf("Излизане от основната програма\n");
връщане0;
}

Видове резби

Когато нишка се върне от основен () функция в приложение, всички нишки прекратяват и системата освобождава всички използвани от програмата ресурси. По същия начин, когато излизате от нишка с команда като an изход(), вашата програма ще прекрати всички нишки.

С pthread_join вместо това можете да изчакате нишката да приключи. Нишката, използваща тази функция, ще блокира, докато очакваната нишка приключи. Ресурсите, които използват от системата, не се връщат дори в случаи като прекратяване на нишки, които могат да се присъединят, непланирани от процесора или дори неуспешно присъединяване с ptread_join.

Понякога има ситуации, при които присъединяването с pthread_join няма смисъл; ако е невъзможно да се предвиди кога нишката ще приключи, например. В този случай можете да гарантирате, че системата връща всички ресурси автоматично в точката, където нишката се връща.

За да постигнете това, трябва да започнете съответните теми с ОТДЕЛЕН състояние. Когато стартирате нишка, ОТКАЧВАНЕ състояние може да се зададе чрез стойности на атрибут на нишка или с pthread_detach функция:

вътрpthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
вътрpthread_detach(pthread_t нишка);

Ето примерна употреба на pthread_join(). Заменете основната функция в първата програма със следното:

вътросновен(невалиден)
{
pthread_t th1, th2;
pthread_create(&th1, НУЛА, работник, "X");
pthread_create(&th2, НУЛА, работник, "Y");
сън(5);
printf("излизане от основната програма\n");
pthread_join (th1, НУЛА);
pthread_join (th2, НУЛА);
връщане0;
}

Когато компилирате и стартирате програмата, изходът ви ще бъде:

Здравейте от нишката Y
Здравейте от тема X
Здравейте от нишката Y
...
Здравейте от нишката Y
излизане от основната програма
Здравейте от тема X
...
Здравейте от тема X
Темата X готова!
Здравейте от нишката Y
Нишката Y е готова!

Прекратяване на нишка

Можете да отмените нишка с извикване на pthread_cancel, предавайки съответния pthread_t документ за самоличност:

вътрpthread_cancel(pthread_t нишка);

Можете да видите това в действие в следния код. Отново само основен функцията е различна:

вътросновен(невалиден)
{
pthread_t th1, th2;
pthread_create(&th1, НУЛА, работник, "X");
pthread_create(&th2, НУЛА, работник, "Y");
сън(1);
printf("> Анулиране на тема Y!!\n");
pthread_cancel (th2);
спим(100000);
printf("> Анулиране на нишка X!\n");
pthread_cancel (th1);
printf("излизане от основната програма\n");
връщане0;
}

Защо се създават нишки?

Операционните системи винаги се опитват да изпълняват нишки на един или повече процесори, или от самостоятелно създаден списък, или от списък с нишки, създаден от потребителя. Някои нишки не могат да се изпълняват, защото чакат входно/изходен сигнал от хардуера. Те може също така да чакат доброволно, да чакат отговор от друга нишка или друга нишка да ги блокира.

Можете да коригирате ресурсите, които разпределяте за нишките, които създавате с помощта на pthread. Това може да бъде персонализирана политика за планиране или можете да изберете алгоритми за планиране като FIFO или Round-robin, ако желаете.