2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Thread: Eine Entität in einem Prozess und die Grundeinheit der CPU-Planung und -Verteilung. Der Thread selbst besitzt grundsätzlich keine Systemressourcen, sondern nur einige Ressourcen, die für die Ausführung unerlässlich sind (z. B. einen Programmzähler, eine Reihe von Registern und einen Stapel), aber er kann alle Ressourcen, die der Prozess besitzt, mit anderen Threads teilen die zum selben Prozess gehören. Ein Thread kann einen anderen Thread erstellen und zerstören; mehrere Threads im selben Prozess können gleichzeitig ausgeführt werden. Threads zeigen während des Betriebs intermittierendes Verhalten. (Das Obige stammt aus „Computer Level 4 Tutorial – Betriebssystemprinzipien“)
Wenn es um Threads geht, muss über die Definition von Prozessen gesprochen werden: Ein Prozess ist ein Programm mit bestimmten unabhängigen Funktionen. Ein Prozess ist eine unabhängige Einheit für die Ressourcenzuweisung und -planung im System. (Das Obige stammt aus „Computer Level 4 Tutorial – Betriebssystemprinzipien“)
Die Definition von Prozess ist etwas kompliziert. Schauen wir uns an, woraus ein Prozess besteht: Programm, Daten und Prozesssteuerungsblock. Unter diesen entspricht das Programm „einem Programm mit bestimmten unabhängigen Funktionen“ in der Prozessdefinition. Zusätzlich zum Programm selbst benötigt der Prozess jedoch auch Daten (die als Ressourcen verstanden werden können) und Prozesssteuerungsblöcke. Daten- und Prozesssteuerungsblöcke sind wesentliche Ressourcen, wenn ein Programm ausgeführt wird. Das Programm ist auf diese Ressourcen angewiesen, um entsprechende Aktivitäten auszuführen, was wir als „Prozess“ bezeichnen.
Zwei grundlegende Eigenschaften von Prozessen:
Ein Prozess ist eine unabhängige Einheit, die Ressourcen besitzen kann;
Ein Prozess ist eine Grundeinheit, die unabhängig geplant und versendet werden kann.
Als Threads zum ersten Mal eingerichtet wurden, dienten sie dazu, die beiden oben genannten Attribute des Prozesses zu trennen. Threads bilden die „Grundeinheit der CPU-Planung und -Verteilung“. Auf diese Weise kann es viele Threads in einem Prozess geben, und das Betriebssystem kann planen und Threads besser versenden Es kann die parallele Ausführung von Prozessen gleichzeitig realisieren, Threads unter demselben Prozess können alle Ressourcen des Prozesses gemeinsam nutzen, was den Zugriff auf Prozessressourcen durch verschiedene Threads unter demselben Prozess erfüllen kann. Durch die Entstehung von Threads werden die beiden Attribute des Prozesses geschickt getrennt, sodass der Prozess die Anforderungen der parallelen Ausführung besser erfüllen kann.
Ein Thread ist eine laufende Funktion. POSIX-Threads sind eine Reihe von Standards, keine Reihe von Implementierungen. Es gibt andere Standards wie zum Beispiel: OpenMP-Threads.
Thread-ID: pthread_t (Ich kenne den spezifischen Inhalt nicht, jedes Unternehmen implementiert ihn anders, unter Linux ist er int)
Der Befehl px axm erkennt Prozesse und Threads – also Threads unter einem Prozess. px ax -L, um Lightweight-Threads anzuzeigen.
int pthread_equal(pthread_t t1, pthread_t t2); Vergleichen Sie die ID-Nummern zweier Threads. Wenn sie gleich sind, wird ein Wert ungleich Null zurückgegeben; wenn sie unterschiedlich sind, wird 0 zurückgegeben.
pthread_t pthread_self(void); Holen Sie sich die Thread-ID des aktuellen Threads
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
Die Thread-Planung hängt von der Strategie des Planers ab.
- #include <stdlib.h>
- #include <stdio.h>
- #include <pthread.h>
- #include <string.h>
-
- void* myfunc(void *p)
- {
- puts("Thread is run!");
-
- printf("thread %ld n",pthread_self());
- return NULL;
- }
-
- int main()
- {
- puts("Begin!");
- pthread_t tid;
- int ret;
- ret = pthread_create(&tid,NULL,myfunc ,NULL);
- if(ret)
- {
- fprintf(stderr,"%s n",strerror(ret));
- exit(1);
- }
- printf("main %ld n",pthread_self());
-
-
-
- puts("End!");
- }
1. Der Thread kehrt von der Startroutine zurück und der Rückgabewert ist der Exit-Code des Threads.
2. Threads können von anderen Threads im selben Prozess abgebrochen werden.
3. Der Thread ruft die Funktion pthread_exit() auf. void pthread_exit(void *retval);
int pthread_join(pthread_t thread, void **retval); Es entspricht dem Warten des Prozesses und wird zum Sammeln von Leichen verwendet.
- #include <stdlib.h>
- #include <stdio.h>
- #include <pthread.h>
- #include <string.h>
-
- void* myfunc(void *p)
- {
- puts("Thread is run!");
-
- pthread_exit(NULL);//线程专用清理函数。
- // return NULL;
- }
-
-
- int main()
- {
- puts("Begin!");
- pthread_t tid;
- int ret;
- ret = pthread_create(&tid,NULL,myfunc ,NULL);
- if(ret)
- {
- fprintf(stderr,"%s n",strerror(ret));
- exit(1);
- }
- pthread_join(tid,NULL); //收尸
-
- puts("End!");
- }
pthread_cleanup_push(); //Entspricht atexit
pthread_cleanup_pop(); //Entspricht dem aktiven Abrufen von Daten.
void pthread_cleanup_push(void (*routine)(void *) ist die Implementierung des Makros gcc -E zum Anzeigen der Vorverarbeitung
ungültig *arg);
void pthread_cleanup_pop(intexe); //Wählen Sie, ob aufgerufen werden soll.Muss paarweise erscheinen, implementiert mit Makros
- #include <stdlib.h>
- #include <stdio.h>
- #include <pthread.h>
- #include <string.h>
-
-
- void cleanup_fun(void*p)
- {
- puts(p);
- }
-
- void* myfunc(void *p)
- {
- puts("Thread is run!");
-
- pthread_cleanup_push(cleanup_fun,"cleanup:1");
- pthread_cleanup_push(cleanup_fun,"cleanup:2");
- pthread_cleanup_push(cleanup_fun,"cleanup:3");
-
- puts("push over!");
-
-
-
- pthread_exit(NULL);//线程专用清理函数。
- // return NULL;
- pthread_cleanup_pop(1) //线程退出后,全部都会调用;
- pthread_cleanup_pop(0);
- pthread_cleanup_pop(1);
- }
-
-
- int main()
- {
- puts("Begin!");
- pthread_t tid;
- int ret;
- ret = pthread_create(&tid,NULL,myfunc ,NULL);
- if(ret)
- {
- fprintf(stderr,"%s n",strerror(ret));
- exit(1);
- }
- pthread_join(tid,NULL); //收尸
-
- puts("End!");
- }
Wenn der laufende Thread die Leiche einsammeln möchte, muss er zuerst abbrechen (pthread_cancel) und dann die Leiche einsammeln (pthread_join).
Thread-Abbruch: int pthread_cancel(pthread_t thread);
Die Stornierung hat zwei Status: erlaubt und nicht erlaubt.
Stornierung nicht zulässig: Die Codeausführung wird unbeeinträchtigt fortgesetzt.
Der zulässige Abbruch ist unterteilt in: asynchronen Abbruch und verzögerten Abbruch (Standard) -> verzögerte Antwort bis zum Abbruchpunkt.
Abbruchpunkt: Die von Posix definierten Abbruchpunkte sind Systemaufrufe, die zu einer Überlastung führen können.
pthread_setcancelstate: Der Abbruchstatus kann festgelegt werden.
pthread_setcanceltype: Sie können die Abbruchmethode festlegen.
pthread_testcancel: Die Funktion macht nichts, bricht nur den Punkt ab.
Thread-Ablösung: int pthread_detach(pthread_t thread);
Dynamische Modul-Einzelinitialisierungsfunktion: int pthread_once(pthread_once_t *once_control,
void (*init_routine)(void));
pthread_once_t einmal_Steuerung = PTHREAD_ONCE_INIT;
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
- #define LEFT 30000000
- #define RIGHT 30000200
- #define THRNUM (RIGHT-LEFT+1)
-
- void* thr_prime(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
- for(i =LEFT;i<=RIGHT;i++)
- {
- err= pthread_create(tid+(i-LEFT),NULL,thr_prime,&i);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- }
-
- for(i=LEFT;i<=RIGHT;i++)
- {
- pthread_join(tid[i-LEFT],NULL);
- }
-
- return 0;
- }
-
- void* thr_prime(void*p)
- {
- int i,j,mark;
-
- i = *(int*)p;
-
- mark = 1;
- for(j=2;j<i/2;j++)
- {
- if(i%j ==0)
- {
- mark = 0;
- break;
- }
- }
- if(mark)
- printf("%d is a primer n",i);
- pthread_exit(NULL);
- return NULL;
- }
Wenn der obige Code ausgeführt wird, wird es Konkurrenz geben. Da Parameter per Adresse übergeben werden, müssen die Daten per * abgerufen werden und es gibt keine Garantie dafür, ob der vorherige Thread die Operation ausgeführt hat. Die einfachste Methode ist die Wertübergabe.
primer0.c
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
- #define LEFT 30000000
- #define RIGHT 30000200
- #define THRNUM (RIGHT-LEFT+1)
-
- void* thr_prime(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
- for(i =LEFT;i<=RIGHT;i++)
- {
- err= pthread_create(tid+(i-LEFT),NULL,thr_prime,(void *)i);
- // err= pthread_create(tid+(i-LEFT),NULL,thr_prime,&i);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- }
-
- for(i=LEFT;i<=RIGHT;i++)
- {
- pthread_join(tid[i-LEFT],NULL);
- }
-
- return 0;
- }
-
- void* thr_prime(void*p)
- {
- int i,j,mark;
-
- i = (int)p;
- // i = *(int*)p;
-
- mark = 1;
- for(j=2;j<i/2;j++)
- {
- if(i%j ==0)
- {
- mark = 0;
- break;
- }
- }
- if(mark)
- printf("%d is a primer n",i);
- pthread_exit(NULL);
- return NULL;
- }
primer0_e.c
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
-
- #define LEFT 30000000
- #define RIGHT 30000200
- #define THRNUM (RIGHT-LEFT+1)
-
- struct thr_arg_st
- {
- int n;
- };
-
- void* thr_prime(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
- struct thr_arg_st* p;
- void *ptr;
- for(i =LEFT;i<=RIGHT;i++)
- {
- p = malloc(sizeof(*p));
- if(p ==NULL)
- {
- perror("malloc");
- exit(1);
- }
- p->n = i;
- err= pthread_create(tid+(i-LEFT),NULL,thr_prime,p); // p就是结构体指针就是n的地址
- // err= pthread_create(tid+(i-LEFT),NULL,thr_prime,&i);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- //free 不能在这里free,必须取走数据在free
- }
-
- for(i=LEFT;i<=RIGHT;i++)
- {
- pthread_join(tid[i-LEFT],&ptr);// 收尸并且接受返回参数。
- free(ptr);
-
- }
-
- return 0;
- }
-
- void* thr_prime(void*p)
- {
- int i,j,mark;
-
- i = ((struct thr_arg_st*)p)->n;
-
- mark = 1;
- for(j=2;j<i/2;j++)
- {
- if(i%j ==0)
- {
- mark = 0;
- break;
- }
- }
- if(mark)
- printf("%d is a primer n",i);
- pthread_exit(p); //返回值返回p
- return NULL;
- }
add.c
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
-
- #define FILENAME "/tmp/out"
- #define THRNUM (20)
-
- void* thr_add(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
- for(i =0;i<=THRNUM;i++)
- {
- err= pthread_create(tid+(i),NULL,thr_add,NULL);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- }
-
- for(i=0;i<=THRNUM;i++)
- {
- pthread_join(tid[i],NULL);
- }
-
- return 0;
- }
-
- void* thr_add(void*p)
- {
- FILE*fp;
- char line_buf[1024];
- int len_size = 1024;
- fp = fopen(FILENAME,"r+");
-
- fgets(line_buf,len_size,fp);
-
- fseek(fp,0,SEEK_SET);
-
- fprintf(fp,"%d n",atoi(line_buf)+1);
-
- fclose(fp);
-
- pthread_exit(NULL);
-
- return NULL;
- }
Konkurrenz und Konflikte können auftreten, wenn zwanzig Threads gleichzeitig Daten in einer Datei lesen und schreiben. Bevor ein Thread einschreibt, liest ein anderer Thread die letzten Daten.
- #include <stdlib.h>
- #include <stdio.h>
- #include <error.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <signal.h>
- #include <pthread.h>
-
- #include "mytbf.h"
-
- struct mytbf_st
- {
- int cps;
- int burst;
- int token;
- int pos;
- pthread_mutex_t mut;
- };
- static pthread_mutex_t mut_job = PTHREAD_MUTEX_INITIALIZER;
- static pthread_t tid_alrm;
- pthread_once_t init_once = PTHREAD_ONCE_INIT;
-
- static struct mytbf_st* job[MYTBF_MAX];
-
- typedef void (*sighandler_t)(int);
-
-
- static int get_free_pos_unlocked(void)
- {
- for(int i=0;i< MYTBF_MAX;i++)
- {
- if(job[i]==NULL)
- return i;
- }
- return -1;
- }
-
- static void* thr_alrm(void*p)
- {
- while(1)
- {
- pthread_mutex_lock(&mut_job);
- for(int i=0;i<MYTBF_MAX;i++)
- {
- if(job[i] != NULL)
- {
- pthread_mutex_lock(&job[i]->mut);
- job[i]->token += job[i]->cps;
- if(job[i]->token >job[i]->burst )
- {
- job[i]->token = job[i]->burst;
- }
- pthread_mutex_unlock(&job[i]->mut);
- }
- }
- pthread_mutex_unlock(&mut_job);
- sleep(1);
- }
- return NULL;
- }
-
- static void module_unload()
- {
- pthread_cancel(tid_alrm);
- pthread_join(tid_alrm,NULL);
- //只能一个人掉,二个人调用容易出差
- for(int i=0;i<MYTBF_MAX;i++)
- {
- if(job[i]!=NULL)
- {
- mytbf_destroy(job[i]);
- }
- }
- pthread_mutex_destroy(&mut_job);
-
- }
-
- static void module_load()
- {
- int err;
- err = pthread_create(&tid_alrm,NULL,thr_alrm,NULL);
- if(err)
- {
- fprintf(stderr,"create errorn");
- exit(1);
- }
- atexit(module_unload);
- }
-
- mytbf_t* mytbf_init(int cps ,int burst) //C语言中,void*可以赋值给任何类型的指针,任何类型的指针也都可以赋值给void*
- {
- struct mytbf_st*me;
- int pos;
- pthread_once(&init_once,module_load); //只初始化一次
- me = malloc(sizeof(*me));
- if(me == NULL)
- return NULL;
-
- me->cps = cps;
- me->burst = burst;
- me->token = 0;
-
- pthread_mutex_init(&me->mut,NULL);
-
- pthread_mutex_lock(&mut_job);
-
- pos = get_free_pos_unlocked();
- if(pos < 0)
- {
-
- pthread_mutex_unlock(&mut_job);
- free(me);
- return NULL;
- }
- me->pos = pos;
- job[pos] = me;
-
- pthread_mutex_unlock(&mut_job);
-
- return me;
-
- }
- int mytbf_fetchtoken(mytbf_t*ptr,int size) //获取token
- {
- if(size <= 0)
- return -EINVAL; //参数非法
- struct mytbf_st*me = ptr;
- pthread_mutex_lock(&me->mut);
- while(me->token <= 0 ) //token为空就等待
- {
- pthread_mutex_unlock(&me->mut);
- sched_yield();
- pthread_mutex_lock(&me->mut);
- }
-
- int n = (me->token>size?size:me->token);
- me->token -= n;
- pthread_mutex_unlock(&me->mut);
- return n;
- }
-
- int mytbf_returntoken(mytbf_t*ptr,int size) //返还token
- {
- if(size<=0)
- return -EINVAL;
- struct mytbf_st*me = ptr;
-
- pthread_mutex_lock(&me->mut);
-
- me->token+= size;
- if(me->token > me->burst)
- me->token = me->burst;
-
- pthread_mutex_unlock(&me->mut);
- return size;
- }
-
- int mytbf_destroy(mytbf_t*ptr)
- {
- struct mytbf_st *me;
- me = ptr;
- pthread_mutex_lock(&mut_job);
- job[me->pos] = NULL;
- pthread_mutex_unlock(&mut_job);
- pthread_mutex_destroy(&me->mut);
- free(ptr);
- return 0;
-
- }
Es entspricht einem Schloss, das entriegelt werden muss, bevor es betätigt werden kann. (Abfragemethode)
Wenn man pthread_mutex_init einen Fehler meldet, installieren Sie bitte die Abhängigkeiten:
sudo apt-get installiere manpages-posix manpages-posix-dev
int pthread_mutex_destroy(pthread_mutex_t *mutex); //Zerstöre die Sperre
int pthread_mutex_init(pthread_mutex_t *mutex einschränken,
const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; statische Initialisierung
int pthread_mutex_lock(pthread_mutex_t *mutex); // kein Thread
int pthread_mutex_trylock(pthread_mutex_t *mutex);//Versuchen Sie zu sperren, wenn nicht, fahren Sie mit der Ausführung fort
int pthread_mutex_unlock(pthread_mutex_t *mutex);//Entsperren
add.c
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
-
- #define FILENAME "/tmp/out"
- #define THRNUM (20)
-
- pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
-
- void* thr_add(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
- for(i =0;i<THRNUM;i++)
- {
- err= pthread_create(tid+(i),NULL,thr_add,NULL);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- }
-
- for(i=0;i<THRNUM;i++)
- {
- pthread_join(tid[i],NULL);
- }
- pthread_mutex_destroy(&mut);
- return 0;
- }
-
- void* thr_add(void*p)
- {
- FILE*fp;
- char line_buf[1024];
- int len_size = 1024;
-
- pthread_mutex_lock(&mut);
-
-
- fp = fopen(FILENAME,"r+");
- fgets(line_buf,len_size,fp);
-
- fseek(fp,0,SEEK_SET);
-
- fprintf(fp,"%d n",atoi(line_buf)+1);
- fclose(fp);
- pthread_mutex_unlock(&mut);
-
- pthread_exit(NULL);
-
- return NULL;
- }
abcd.c
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
-
- #define FILENAME "/tmp/out"
- #define THRNUM (4)
-
- pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
-
- void* thr_abcd(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
- for(i =0;i<THRNUM;i++)
- {
- err= pthread_create(tid+(i),NULL,thr_abcd,(void*)i);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- }
- alarm(2);
-
- for(i=0;i<THRNUM;i++)
- {
- pthread_join(tid[i],NULL);
- }
- pthread_mutex_destroy(&mut);
- return 0;
- }
-
- void* thr_abcd(void*p)
- {
- int c = 'a'+ (int)p;
- while(1)
- {
- write(1,&c,1);
- }
-
- pthread_exit(NULL);
-
- return NULL;
- }
abcd.c
Verwenden Sie die Kette zum Ver- und Entriegeln.
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
-
- #define FILENAME "/tmp/out"
- #define THRNUM (4)
-
- pthread_mutex_t mut[THRNUM];
-
- void* thr_abcd(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
- for(i =0;i<THRNUM;i++)
- {
- pthread_mutex_init(mut+i,NULL); //初始化四个锁
- pthread_mutex_lock(mut+i);
-
- err= pthread_create(tid+(i),NULL,thr_abcd,(void*)i);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- }
- pthread_mutex_unlock(mut+0);
- alarm(2);
-
- for(i=0;i<THRNUM;i++)
- {
- pthread_join(tid[i],NULL);
- }
- pthread_mutex_destroy(&mut);
- return 0;
- }
- int next(int n)
- {
- if(n +1 ==THRNUM)
- return 0;
- return n+1;
- }
- void* thr_abcd(void*p)
- {
- int c = 'a'+ (int)p;
- int n = (int)p;
- while(1)
- {
- pthread_mutex_lock(mut+n);
- write(1,&c,1);
- pthread_mutex_unlock(mut+next(n) );
- }
- pthread_exit(NULL);
-
- return NULL;
- }
Der Pool-Algorithmus implementiert die Primzahlberechnung (Abfragemethode).
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
- #define LEFT 30000000
- #define RIGHT 30000200
- #define THRNUM (RIGHT-LEFT+1)
-
- void* thr_prime(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
- for(i =LEFT;i<=RIGHT;i++)
- {
- err= pthread_create(tid+(i-LEFT),NULL,thr_prime,(void *)i);
- // err= pthread_create(tid+(i-LEFT),NULL,thr_prime,&i);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- }
-
- for(i=LEFT;i<=RIGHT;i++)
- {
- pthread_join(tid[i-LEFT],NULL);
- }
-
- return 0;
- }
-
- void* thr_prime(void*p)
- {
- int i,j,mark;
-
- i = (int)p;
- // i = *(int*)p;
-
- mark = 1;
- for(j=2;j<i/2;j++)
- {
- if(i%j ==0)
- {
- mark = 0;
- break;
- }
- }
- if(mark)
- printf("%d is a primer n",i);
- pthread_exit(NULL);
- return NULL;
- }
Mitteilungsgesetz für Kommunikation.
: In diesem Artikel wird pthread_cond_destroy.exe beschrieben.
int pthread_cond_init(pthread_cond_t *Bedingung einschränken,
const pthread_condattr_t *attr einschränken);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_broadcast(pthread_cond_t *cond); //Weckt alle Wartenden auf
int pthread_cond_signal(pthread_cond_t *cond);//Wende alle Wartezeiten auf
int pthread_cond_timedwait(pthread_cond_t *restrict cond, //timeout wait
pthread_mutex_t *Mutex einschränken,
const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond, //Bedingung einschränken
pthread_mutex_t *Mutex einschränken);
mytbf.c (Benachrichtigungsmethode)
- #include <stdlib.h>
- #include <stdio.h>
- #include <error.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <signal.h>
- #include <pthread.h>
-
- #include "mytbf.h"
-
- struct mytbf_st
- {
- int cps;
- int burst;
- int token;
- int pos;
- pthread_mutex_t mut;
- pthread_cond_t cond;
-
- };
- static pthread_mutex_t mut_job = PTHREAD_MUTEX_INITIALIZER;
- static pthread_t tid_alrm;
- pthread_once_t init_once = PTHREAD_ONCE_INIT;
-
- static struct mytbf_st* job[MYTBF_MAX];
-
- typedef void (*sighandler_t)(int);
-
-
- static int get_free_pos_unlocked(void)
- {
- for(int i=0;i< MYTBF_MAX;i++)
- {
- if(job[i]==NULL)
- return i;
- }
- return -1;
- }
-
- static void* thr_alrm(void*p)
- {
- while(1)
- {
- pthread_mutex_lock(&mut_job);
- for(int i=0;i<MYTBF_MAX;i++)
- {
- if(job[i] != NULL)
- {
- pthread_mutex_lock(&job[i]->mut);
- job[i]->token += job[i]->cps;
- if(job[i]->token >job[i]->burst )
- {
- job[i]->token = job[i]->burst;
- }
- pthread_cond_broadcast(&job[i]->cond);
- pthread_mutex_unlock(&job[i]->mut);
- }
- }
- pthread_mutex_unlock(&mut_job);
- sleep(1);
- }
- return NULL;
- }
-
- static void module_unload()
- {
- pthread_cancel(tid_alrm);
- pthread_join(tid_alrm,NULL);
- //只能一个人掉,二个人调用容易出差
- for(int i=0;i<MYTBF_MAX;i++)
- {
- if(job[i]!=NULL)
- {
- mytbf_destroy(job[i]);
- }
- }
- pthread_mutex_destroy(&mut_job);
-
- }
-
- static void module_load()
- {
- int err;
- err = pthread_create(&tid_alrm,NULL,thr_alrm,NULL);
- if(err)
- {
- fprintf(stderr,"create errorn");
- exit(1);
- }
- atexit(module_unload);
- }
-
- mytbf_t* mytbf_init(int cps ,int burst) //C语言中,void*可以赋值给任何类型的指针,任何类型的指针也都可以赋值给void*
- {
- struct mytbf_st*me;
- int pos;
- pthread_once(&init_once,module_load); //只初始化一次
- me = malloc(sizeof(*me));
- if(me == NULL)
- return NULL;
-
- me->cps = cps;
- me->burst = burst;
- me->token = 0;
-
- pthread_mutex_init(&me->mut,NULL);
- pthread_cond_init(&me->cond,NULL);
- pthread_mutex_lock(&mut_job);
-
- pos = get_free_pos_unlocked();
- if(pos < 0)
- {
-
- pthread_mutex_unlock(&mut_job);
- free(me);
- return NULL;
- }
- me->pos = pos;
- job[pos] = me;
-
- pthread_mutex_unlock(&mut_job);
-
- return me;
-
- }
- int mytbf_fetchtoken(mytbf_t*ptr,int size) //获取token
- {
- if(size <= 0)
- return -EINVAL; //参数非法
- struct mytbf_st*me = ptr;
- pthread_mutex_lock(&me->mut);
- while(me->token <= 0 ) //token为空就等待
- {
- pthread_cond_wait(&me->cond,&me->mut); //解锁等待,等待conad_broadcast和conad_signal的到来
-
- /*
- pthread_mutex_unlock(&me->mut);
- sched_yield();
- pthread_mutex_lock(&me->mut);
- */
- }
-
-
- int n = (me->token>size?size:me->token);
- me->token -= n;
- pthread_mutex_unlock(&me->mut);
- return n;
- }
-
- int mytbf_returntoken(mytbf_t*ptr,int size) //返还token
- {
- if(size<=0)
- return -EINVAL;
- struct mytbf_st*me = ptr;
-
- pthread_mutex_lock(&me->mut);
-
- me->token+= size;
- if(me->token > me->burst)
- me->token = me->burst;
- pthread_cond_broadcast(&me->cond);
- pthread_mutex_unlock(&me->mut);
- return size;
- }
-
- int mytbf_destroy(mytbf_t*ptr)
- {
- struct mytbf_st *me;
- me = ptr;
- pthread_mutex_lock(&mut_job);
- job[me->pos] = NULL;
- pthread_mutex_unlock(&mut_job);
- pthread_mutex_destroy(&me->mut);
- pthread_cond_destroy(&me->cond);
- free(ptr);
- return 0;
-
- }
primer0_pool.c
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
- #include <sched.h>
-
- #define LEFT 30000000
- #define RIGHT 30000200
- #define THRNUM (4)
-
- static int num = 0;
- static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
- static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-
- void* thr_prime(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
-
- for(i =0;i<=THRNUM;i++)
- {
- err= pthread_create(tid+(i),NULL,thr_prime,(void *)i);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- }
- //下发任务
- for(i=LEFT;i<RIGHT;i++)
- {
- pthread_mutex_lock(&mut);
- while(num !=0) //不是0就需要等待任务被取走
- {
- pthread_cond_wait(&cond,&mut);
- }
-
- num = i; //下发任务
- pthread_cond_signal(&cond); //下游叫醒任意一个
- pthread_mutex_unlock(&mut);
- }
- pthread_mutex_lock(&mut);
- while(num!= 0)
- {
- pthread_mutex_unlock(&mut);
- sched_yield(); //出让调度器给别的线程
- }
- num = -1; //用于线程退出
- pthread_cond_broadcast(&cond);
-
- pthread_mutex_unlock(&mut);
-
- for(i=0;i<=THRNUM;i++)
- {
- pthread_join(tid[i],NULL);
- }
- pthread_mutex_destroy(&mut);
- pthread_cond_destroy(&cond);
- return 0;
- }
-
- void* thr_prime(void*p)
- {
- int i,j,mark;
- while(1)
- {
- pthread_mutex_lock(&mut);
- while(num == 0)
- {
- pthread_cond_wait(&cond,&mut);
- }
- if(num == -1)
- {
- pthread_mutex_unlock(&mut); //走到这里必须要解锁。
- break;
- }
-
- i= num;
- num = 0;
- pthread_cond_broadcast(&cond);
-
- pthread_mutex_unlock(&mut);
-
- mark = 1;
- for(j=2;j<i/2;j++)
- {
- if(i%j ==0)
- {
- mark = 0;
- break;
- }
- }
- if(mark)
- printf("[%d]%d is a primer n",(int)p,i);
- }
-
- pthread_exit(NULL);
- return NULL;
- }
abcd_cond.c
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
-
- #define FILENAME "/tmp/out"
- #define THRNUM (4)
-
- pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
- int num;
-
- void* thr_abcd(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
- for(i =0;i<THRNUM;i++)
- {
-
- err= pthread_create(tid+(i),NULL,thr_abcd,(void*)i);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- }
-
- alarm(2);
-
- for(i=0;i<THRNUM;i++)
- {
- pthread_join(tid[i],NULL);
- }
- pthread_cond_destroy(&cond);
- pthread_mutex_destroy(&mut);
- return 0;
- }
- int next(int n)
- {
- if(n +1 ==THRNUM)
- return 0;
- return n+1;
- }
- void* thr_abcd(void*p)
- {
- int c = 'a'+ (int)p;
- int n = (int)p;
- while(1)
- {
- pthread_mutex_lock(&mut);
- while(num != n)
- {
- pthread_cond_wait(&cond,&mut);
- }
- write(1,&c,1);
- num = next(num);
- pthread_cond_broadcast(&cond);
- pthread_mutex_unlock(&mut );
- }
- pthread_exit(NULL);
-
- return NULL;
- }
Der Mutex ist vom Typ bool und der Semaphor ist vom Typ int. Er dekrementiert sich selbst, wenn er nicht ausreicht, wartet er.
mysem.c
- #include <stdlib.h>
- #include <stdio.h>
- #include <pthread.h>
- #include <string.h>
- #include <unistd.h>
- #include "mysem.h"
-
- struct mysem_st
- {
- int value;
- pthread_mutex_t mut;
- pthread_cond_t cond;
-
- };
-
- mysem_t* mysem_init(int initval)
- {
- struct mysem_st*me;
- me = malloc(sizeof(*me));
- if(me==NULL)
- return NULL;
- me->value = initval;
- pthread_mutex_init(&me->mut,NULL);
- pthread_cond_init(&me->cond,NULL);
-
- return me;
-
- }
-
- int mysem_add(mysem_t*ptr ,int n)
- {
- struct mysem_st*me = ptr;
-
- pthread_mutex_lock(&me->mut);
-
- me->value+= n;
- pthread_cond_broadcast(&me->cond);
- pthread_mutex_unlock(&me->mut);
-
- return n;
- }
-
- int mysem_sub(mysem_t*ptr ,int n )
- {
- struct mysem_st*me = ptr;
-
- pthread_mutex_lock(&me->mut);
- while(me->value <n)
- {
- pthread_cond_wait(&me->cond,&me->mut);
- }
- me->value -=n;
-
- pthread_mutex_unlock(&me->mut);
- return n;
- }
-
- void mysem_destroy(mysem_t*ptr)
- {
- struct mysem_st*me = ptr;
- pthread_mutex_destroy(&me->mut);
- pthread_cond_destroy(&me->cond);
- free(me);
- }
-
-
-
mysem.h
- #ifndef MYSEM_H
- #define MYSEM_H
-
- typedef void mysem_t;
-
- mysem_t* mysem_init(int initval);
-
- int mysem_add(mysem_t*,int);
-
- int mysem_sub(mysem_t*,int);
-
- void mysem_destroy(mysem_t*);
-
-
-
- #endif
Haupt c
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <pthread.h>
- #include "mysem.h"
-
- #define LEFT 30000000
- #define RIGHT 30000200
- #define THRNUM (RIGHT-LEFT+1)
-
- #define N 4
- static mysem_t* sem;
-
- void* thr_prime(void*p);
-
- int main()
- {
- pthread_t tid[THRNUM];
- int i,j,mark;
- int err;
-
- sem = mysem_init(N);
- if(sem ==NULL)
- {
- fprintf(stderr,"mysem_init n");
- exit(1);
- }
-
- for(i =LEFT;i<=RIGHT;i++)
- {
- mysem_sub(sem,1);
-
- err= pthread_create(tid+(i-LEFT),NULL,thr_prime,(void *)i);
- if(err)
- {
- fprintf(stderr,"pthread_create():%sn",strerror(err));
- }
- }
-
- for(i=LEFT;i<=RIGHT;i++)
- {
- pthread_join(tid[i-LEFT],NULL);
- }
-
- mysem_destroy(sem);
-
- return 0;
- }
-
- void* thr_prime(void*p)
- {
- int i,j,mark;
-
- i = (int)p;
- // i = *(int*)p;
-
- mark = 1;
- for(j=2;j<i/2;j++)
- {
- if(i%j ==0)
- {
- mark = 0;
- break;
- }
- }
- if(mark)
- printf("%d is a primer n",i);
-
- sleep(5); //ps ax -L 可以观察到对线程进行了限制,只创建了四个线程
-
- mysem_add(sem,1);
- pthread_exit(NULL);
-
- return NULL;
- }
Make-Datei
- all:mysem
- CFLAGS+=-g -Wall -pthread
- LDFLAGS+= -pthread
-
- mysem:main.o mysem.o
- gcc $^ $(CFLAGS) $(LDFLAGS) -o $@
-
- clean:
- rm -rf *.o mysem
Umfassender Einsatz von Mutexes und Semaphoren. Unterteilt in Lesesperre (Semaphor) und Schreibsperre (Mutex). Generell sollte eine Obergrenze für das Lesen und Schreiben festgelegt werden.
Es muss verhindert werden, dass Schriftsteller verhungern.
Der zweite Parameter von pthread_create ist das Attribut des Threads.
pthread_attr_init(pthread_attr_t *attr);
: In diesem Artikel wird beschrieben, wie Sie pthread_attr_destroy mithilfe von pthread_attr_t zerstören.
Die maximale Anzahl der vom Testprogramm erstellten Threads. ()
- #include <stdlib.h>
- #include <stdio.h>
- #include <pthread.h>
-
- void* func(void)
- {
- int i;
-
- // printf("%pn",&i);
- pthread_exit(NULL);
- return NULL;
- }
-
- int main()
- {
- int err;
- pthread_t tid;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setstacksize(&attr,1024*1024); //1mb
-
- int i = 0;
- for(;;i++)
- {
- err = pthread_create(&tid,&attr,func,NULL);
- if(err)
- {
- fprintf(stderr,"create errn");
- break;
- }
- }
- printf("max = %d n",i);
- pthread_attr_destroy(&attr);
- return 0;
- }
Mutex-Eigenschaften:
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
Siehe pthread_mutexattr_destroy().
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, //funktioniert prozessübergreifend
}
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,
}
//Erstellen Sie einen untergeordneten Prozess, der das Dateideskriptor-Array gemeinsam nutzen kann. Sie können es auch nicht freigeben. Unter Linux gibt es keine Unterscheidung zwischen Prozessen und Threads
int-Klon(int (*fn)(void *), void *stack, int-Flags, void *arg, …
/* pid_t *übergeordnete_tid, void *tls, pid_t *untergeordnete_tid */ );
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr einschränken,
int *Typ einschränken);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int Typ);
Eigenschaften der Bedingungsvariablen:
int pthread_condattr_destroy(pthread_condattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);
Eigenschaften der Lese-/Schreibsperre:
Eine wiedereintrittsfähige Funktion ist einfach eine Funktion, die unterbrochen werden kann. Das heißt, Sie können diese Funktion jederzeit während ihrer Ausführung unterbrechen und an die Betriebssystemplanung übergeben, um bei der Rückgabe der Kontrolle einen anderen Code auszuführen Funktionen nutzen einige Systemressourcen, z. B. globale Variablenbereiche, Interrupt-Vektortabellen usw. Wenn sie unterbrochen werden, können solche Funktionen in einer Multitasking-Umgebung nicht ausgeführt werden.
IO im Multithreading. Die entsperrte Funktion endet mit (nicht wiedereintrittsfähige Funktion, Multithread-Parallelität wird nicht unterstützt). man putc_unlocked, nicht unterstützte E/A-Vorgänge anzeigen.
int pthread_sigmask(int wie, const sigset_t *set, sigset_t *oldset);
sigwait(const sigset_t *set, int *sig);
int pthread_kill(pthread_t-Thread, int sig);
Weitere Informationen finden Sie auf der offiziellen Website: www.OpenMp.org
Openmp-Syntax-Tags werden nach gcc4.0 unterstützt.Wie viele Parallelitäten können mit nur wenigen CPUs erreicht werden?
Hallo c
- #include <stdio.h>
- #include <stdlib.h>
-
- int main()
- {
- #pragma omp parallel //实现并发
- {
- puts("Hello ");
- puts(" World");
- }
- return 0;
- }
Make-Datei
CFLAGS += -Wall -fopenmp
Kompilieren Sie „make hello“ und führen Sie es aus.
- #include <stdio.h>
- #include <stdlib.h>
- #include <omp.h>
-
- int main()
- {
- #pragma omp parallel sections
- {
- #pragma omp section
- printf("[%d:]Hello n",omp_get_thread_num() );
- #pragma omp section
- printf("[%d:]World n",omp_get_thread_num() );
- }
- return 0;
- }