Narzędzia użytkownika

Narzędzia witryny


sk2:cpp11_threads

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Poprzednia wersja
Nowa wersja
Poprzednia wersja
sk2:cpp11_threads [2024/11/07 14:31]
jkonczak
sk2:cpp11_threads [2024/11/07 23:21] (aktualna)
jkonczak [[ekstra] Wątki w C++]
Linia 1: Linia 1:
 ===== [ekstra] Wątki w C++ ===== ===== [ekstra] Wątki w C++ =====
 Język C+''''​+ (od wersji C+''''​+11) ​ ma w bibliotece standardowej obsługę wątków. \\ Język C+''''​+ (od wersji C+''''​+11) ​ ma w bibliotece standardowej obsługę wątków. \\
-API do obsługi wątków w C+''''​+ zostało przeniesione z ''​boost::​thread'',​ z wyjątkiem obsługi przerywania wątków (''​thread::​interrupt()''​)((W C+''''​+20 pojawiła się klasa ''​std::​jthread''​ która pozwala zasygnalizować wątkowi że powinien się przerwać, ale wywołanie ''​request_stop''​ __nie__ przerywa wywołań systemowych (np. ''​read''​). )).+<​small>​API do obsługi wątków w C+''''​+ zostało przeniesione z ''​boost::​thread'',​ z wyjątkiem obsługi przerywania wątków (''​thread::​interrupt()''​)((W C+''''​+20 pojawiła się klasa ''​std::​jthread''​ która pozwala zasygnalizować wątkowi że powinien się przerwać, ale wywołanie ''​request_stop''​ __nie__ przerywa wywołań systemowych (np. ''​read''​). )).</​small>​
  
 Przykład prostego programu: Przykład prostego programu:
 <​html><​div style="​line-height:​105%;​margin-top:​-1.2em"></​div></​html>​ <​html><​div style="​line-height:​105%;​margin-top:​-1.2em"></​div></​html>​
 <code cpp threadHelloWorld.cpp>​ <code cpp threadHelloWorld.cpp>​
-#include <​thread>​ 
 #include <​cstdio>​ #include <​cstdio>​
-void funkcja(const char * argument){ +#include <​thread>​ 
-    printf("​Hello %s\n", argument);+void funkcja(unsigned count, ​const char *argument) { 
 +    ​while (count--) 
 +        ​printf("​Hello %s\n", argument);
     /* kod wykonywany w drugim wątku */     /* kod wykonywany w drugim wątku */
 } }
-int main(){ +int main() { 
-    std::thread t(funkcja, "​world"​);​+    std::thread t(funkcja, 3, "​world"​);​
     /* kod wykonywany w pierwszym wątku */     /* kod wykonywany w pierwszym wątku */
     t.join();     t.join();
Linia 19: Linia 20:
 } }
 </​code>​ </​code>​
 +<​html><​div style="​margin-top:​-1.2em;​margin-bottom:​-1.2em"></​div></​html>​
 +++++ Odpowiednik kodu w C używający pthreads|
 +<​html><​div style="​line-height:​105%;​margin-top:​-3em"></​div></​html>​
 +<code cpp threadHelloWorld.c>​
 +#include <​pthread.h>​
 +#include <​stdlib.h>​
 +#include <​stdio.h>​
 +
 +struct funkcja_argumenty{
 +    unsigned count;
 +    const char * argument;
 +};
 +
 +void * funkcja(void * rawArgs){
 +    struct funkcja_argumenty *args = rawArgs;
 +    while(args->​count--)
 +        printf("​Hello %s\n", args->​argument);​
 +    free(rawArgs);​
 +    /* kod wykonywany w drugim wątku */
 +    return NULL;
 +}
 +int main(void){
 +    pthread_t tid;
 +    struct funkcja_argumenty *args = malloc(sizeof(struct funkcja_argumenty));​
 +    args->​count = 3;
 +    args->​argument = "​world";​
 +    pthread_create(&​tid,​ NULL, funkcja, args);
 +    /* kod wykonywany w pierwszym wątku */
 +    pthread_join(tid,​ NULL);
 +    return 0;
 +}
 +</​code>​
 +++++
  
 Podsumowanie tworzenia wątków: Podsumowanie tworzenia wątków:
Linia 47: Linia 81:
  
 <​small>​ <​small>​
-W C++ ustandaryzowano też zmienne lokalne dla wątku – w deklaracji zmiennej wystarczy dodać słowo kluczowe ''​thread_local'',​ np:+W C+%%%%+ ustandaryzowano też zmienne lokalne dla wątku – w deklaracji zmiennej wystarczy dodać słowo kluczowe ''​thread_local'',​ np:
 <​html><​div style="​line-height:​105%;​margin-top:​-1.2em"></​div></​html>​ <​html><​div style="​line-height:​105%;​margin-top:​-1.2em"></​div></​html>​
 <code cpp> <code cpp>
Linia 59: Linia 93:
  
 Przykład synchronizacji między wątkami (producent-konsument):​ Przykład synchronizacji między wątkami (producent-konsument):​
 +<​html><​div style="​line-height:​105%;​margin-top:​-1.2em"></​div></​html>​
 <code cpp condVarHelloWorld.cpp>​ <code cpp condVarHelloWorld.cpp>​
 #include <​condition_variable>​ #include <​condition_variable>​
Linia 100: Linia 135:
 } }
 </​code>​ </​code>​
 +<​html><​div style="​margin-top:​-1.2em;​margin-bottom:​-1.2em"></​div></​html>​
 +++++ Odpowiednik kodu w C używający pthreads|
 +<​html><​div style="​line-height:​105%;​margin-top:​-3em"></​div></​html>​
 +<code cpp condVarHelloWorld.c>​
 +#include <​pthread.h>​
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +#include <​string.h>​
 +
 +struct dumbQueue *msgQueue;
 +
 +struct dumbQueue* dumbQueue_create (void);
 +            void  dumbQueue_push ​  ​(struct dumbQueue *q, void *element);
 +            void* dumbQueue_pop ​   (struct dumbQueue *q);
 +             ​int ​ dumbQueue_isEmpty(struct dumbQueue *q);
 +
 +pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;​
 +pthread_cond_t ​ cv  = PTHREAD_COND_INITIALIZER;​
 +
 +_Thread_local char *msg;
 +
 +void producer(void) {
 +    while (1) {
 +        msg = malloc(255);​
 +        scanf("​%*[\n]"​);​
 +        scanf("​%254[^\n]",​ msg);
 +        {
 +            pthread_mutex_lock(&​mtx);​
 +            dumbQueue_push(msgQueue,​ msg);
 +            pthread_cond_signal(&​cv);​
 +            pthread_mutex_unlock(&​mtx);​
 +        }
 +    }
 +}
 +
 +void *consumer(void *_) {
 +    while (1) {
 +        {
 +            pthread_mutex_lock(&​mtx);​
 +            while (dumbQueue_isEmpty(msgQueue))
 +                pthread_cond_wait(&​cv,​ &mtx);
 +            msg = dumbQueue_pop(msgQueue);​
 +            pthread_mutex_unlock(&​mtx);​
 +        }
 +        printf("​%s\n",​ msg);
 +        free(msg);
 +    }
 +}
 +
 +int main(void) {
 +    msgQueue = dumbQueue_create();​
 +    pthread_t tid;
 +    pthread_create(&​tid,​ NULL, consumer, NULL);
 +    producer();
 +}
 +
 +/​*****/ ​ struct dumbQueue {
 +/* T */      struct dumbQueue_e {
 +/* h */          void *element;
 +/* i */          struct dumbQueue_e *next;
 +/* s */      } *head, *tail;
 +/*   ​*/ ​ };
 +/* i */  ​
 +/* s */  struct dumbQueue *dumbQueue_create(void) {
 +/*   ​*/ ​     struct dumbQueue *q = malloc(sizeof(struct dumbQueue));​
 +/* j */      q->head = malloc(sizeof(struct dumbQueue_e));​
 +/* u */      q->​head->​next = NULL;
 +/* s */      q->tail = q->head;
 +/* t */      return q;
 +/*   ​*/ ​ }
 +/* a */  ​
 +/*   ​*/ ​ void dumbQueue_push(struct dumbQueue *q, void *element) {
 +/* d */      q->​tail->​next = malloc(sizeof(struct dumbQueue_e));​
 +/* u */      q->tail = q->​tail->​next;​
 +/* m */      q->​tail->​next = NULL;
 +/* b */      q->​tail->​element = element;
 +/*   ​*/ ​ }
 +/* q */  ​
 +/* u */  void *dumbQueue_pop(struct dumbQueue *q) {
 +/* e */      struct dumbQueue_e *next = q->​head->​next;​
 +/* u */      free(q->​head);​
 +/* e */      q->head = next;
 +/*   ​*/ ​     return q->​head->​element;​
 +/* i */  }
 +/* m */  ​
 +/* p */  int dumbQueue_isEmpty(struct dumbQueue *q) {
 +/* l */      return q->​head->​next == NULL;
 +/​*****/ ​ }
 +</​code>​
 +++++
  
 ===== [ekstra] <​functional>​ w C++ ===== ===== [ekstra] <​functional>​ w C++ =====
sk2/cpp11_threads.1730986312.txt.gz · ostatnio zmienione: 2024/11/07 14:31 (edycja zewnętrzna)