Technology sharing

C lingua: concurrency provectus operationes (stamina)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. De conceptu sequelae

Post: Ens in processu et in basic unitas CPU scheduling et litterae. Ipsum filum basically facultates systematis proprias non habet, paucae tantum facultates quae ad currendum necessariae sunt (sicut programma calculi, tabulae tabulae, et acervus), sed communicare potest omnes facultates quae processu cum aliis sequelis habent. quae ad eundem processum pertinent. Filum aliud stamen creare et destruere potest; Fila monstrant mores intermittendi in operatione. (Superius est ex "Computer Level 4 Tutorialis - Ratio Principia Operating")

Cum fila venit, loqui necesse est de definitione processus: processus est programma cum quibusdam functionibus independentibus. (Superius est ex "Computer Level 4 Tutorialis - Ratio Principia Operating")

Definitio processus est aliquantulus perplexa. Inspiciamus quid sit processus: progressio, notitia et processus imperium scandalum. Inter eos, programma respondet "programma cum quibusdam functionibus independentibus" in definitione processus. Data et processus imperium insulis essentiales sunt facultates cum programma currit.

Duae processus principales proprietates:

Processus est unitas independentis quae proprias facultates habere potest;
Processus fundamentalis unitas est quae independenter a schedule et mitti potest.
Cum stamina primum constituta sunt, illa duo processus attributa dividere erat. Fila constituunt "unitatem fundamentalem CPU scheduling et mittentem." et stamina in melius mitti. Potest cognoscere processuum exsecutionem parallelam; simul, fila sub eodem processu omnes facultates processus communicare, quae accessum facultatum processuum diversis stamina sub eodem processu explere possunt. Cessus filorum duo attributa processus callide separat, sino processu ut melius necessarias exsecutionis parallelae tractaret.

Filum munus currens est. Stamina POSIX signa sunt copia, non exsecutiones copiae. Alia sunt signa ut: fila openmp.
Thread identifier: pthread_t (Non novi contentum specificum, singulae societatis instrumentum aliter id, sub Linux int)
Mandatum px axm processus et fila videt - fila repraesentans sub processu. px securi -L ad view relatorum leve.

int pthread_equal(pthread_t t1, pthread_t t2). Si eadem sunt, non- nulla redditur;
pthread_t pthread_self(inanis);

2. De creatione relatorum

int pthread_create (pthread_t * stamina const pthread_attr_t * attr,
void *(*start_routine) (void *), void *arg);
Post scheduling dependet a consilio schedularum.

create1.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <pthread.h>
  4. #include <string.h>
  5. void* myfunc(void *p)
  6. {
  7. puts("Thread is run!");
  8. printf("thread %ld n",pthread_self());
  9. return NULL;
  10. }
  11. int main()
  12. {
  13. puts("Begin!");
  14. pthread_t tid;
  15. int ret;
  16. ret = pthread_create(&tid,NULL,myfunc ,NULL);
  17. if(ret)
  18. {
  19. fprintf(stderr,"%s n",strerror(ret));
  20. exit(1);
  21. }
  22. printf("main %ld n",pthread_self());
  23. puts("End!");
  24. }

Post terminationem

1. Sequela ab exercitatione startup redit, et valor reditus est exitus sequelae.
2. Fila alia fila in eodem processu cassari possunt.
3. Filum vocat munus pthread_exit(). void pthread_exit(void *retval);

int pthread_join(pthread_t thread, inanis retval);

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <pthread.h>
  4. #include <string.h>
  5. void* myfunc(void *p)
  6. {
  7. puts("Thread is run!");
  8. pthread_exit(NULL);//线程专用清理函数。
  9. // return NULL;
  10. }
  11. int main()
  12. {
  13. puts("Begin!");
  14. pthread_t tid;
  15. int ret;
  16. ret = pthread_create(&tid,NULL,myfunc ,NULL);
  17. if(ret)
  18. {
  19. fprintf(stderr,"%s n",strerror(ret));
  20. exit(1);
  21. }
  22. pthread_join(tid,NULL); //收尸
  23. puts("End!");
  24. }

BIBLIOTHECA tersus

pthread_cleanup_push();
pthread_cleanup_pop();

inanis pthread_cleanup_push(inanis (*routine)(inanis *) est exsecutio tortor, gcc -E ad visum preprocessing
void *arg);
vacui pthread_cleanup_pop(int exequi);Apparebit paria, cum macros implemented

cleanup.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <pthread.h>
  4. #include <string.h>
  5. void cleanup_fun(void*p)
  6. {
  7. puts(p);
  8. }
  9. void* myfunc(void *p)
  10. {
  11. puts("Thread is run!");
  12. pthread_cleanup_push(cleanup_fun,"cleanup:1");
  13. pthread_cleanup_push(cleanup_fun,"cleanup:2");
  14. pthread_cleanup_push(cleanup_fun,"cleanup:3");
  15. puts("push over!");
  16. pthread_exit(NULL);//线程专用清理函数。
  17. // return NULL;
  18. pthread_cleanup_pop(1) //线程退出后,全部都会调用;
  19. pthread_cleanup_pop(0);
  20. pthread_cleanup_pop(1);
  21. }
  22. int main()
  23. {
  24. puts("Begin!");
  25. pthread_t tid;
  26. int ret;
  27. ret = pthread_create(&tid,NULL,myfunc ,NULL);
  28. if(ret)
  29. {
  30. fprintf(stderr,"%s n",strerror(ret));
  31. exit(1);
  32. }
  33. pthread_join(tid,NULL); //收尸
  34. puts("End!");
  35. }

Abrigavi optiones relatorum

Si filum currens vult colligere cadaver, oportet primum delere et deinde corpus colligere (pthread_join).

Post tabulae novae: int pthread_cancel(pthread_t thread);
Receptatio duos status habet: licet et non licet.
Indultum receptae non conceditur: signum exsecutionis sine impedimento pergit.
Permissa indultum dividitur in: asynchronum inrita, et retardatum inrita (default) -&gt; responsionis tardae usque ad punctum inrita.
Punctum cancale: Excludit puncta quae Posix definita sunt systema vocat quae obstructionem causare possunt.
pthread_setcancelstate: Abrigavi publica statui potest.
pthread_setcanceltype: Tabulae novae modum constituere potes.
pthread_testcancel: Munus nihil agit, solum punctum tollit.

Reticulum: int pthread_detach(pthread_t thread);

Dynamici moduli unius functionis initialization: int pthread_once(pthread_once_t *once_control,
inanis (*init_routine)(inanis));
pthread_once_t once_control = PTHREAD_ONCE_INIT;
 

Exemplum 1
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #define LEFT 30000000
  7. #define RIGHT 30000200
  8. #define THRNUM (RIGHT-LEFT+1)
  9. void* thr_prime(void*p);
  10. int main()
  11. {
  12. pthread_t tid[THRNUM];
  13. int i,j,mark;
  14. int err;
  15. for(i =LEFT;i<=RIGHT;i++)
  16. {
  17. err= pthread_create(tid+(i-LEFT),NULL,thr_prime,&i);
  18. if(err)
  19. {
  20. fprintf(stderr,"pthread_create():%sn",strerror(err));
  21. }
  22. }
  23. for(i=LEFT;i<=RIGHT;i++)
  24. {
  25. pthread_join(tid[i-LEFT],NULL);
  26. }
  27. return 0;
  28. }
  29. void* thr_prime(void*p)
  30. {
  31. int i,j,mark;
  32. i = *(int*)p;
  33. mark = 1;
  34. for(j=2;j<i/2;j++)
  35. {
  36. if(i%j ==0)
  37. {
  38. mark = 0;
  39. break;
  40. }
  41. }
  42. if(mark)
  43. printf("%d is a primer n",i);
  44. pthread_exit(NULL);
  45. return NULL;
  46. }

Certamen erit cum curritur supra codicem. Quia parametri electronici praetereunt, notitia insanabilis * est, et nulla est cautio an prior filo operationem perficiat.

primer0.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #define LEFT 30000000
  7. #define RIGHT 30000200
  8. #define THRNUM (RIGHT-LEFT+1)
  9. void* thr_prime(void*p);
  10. int main()
  11. {
  12. pthread_t tid[THRNUM];
  13. int i,j,mark;
  14. int err;
  15. for(i =LEFT;i<=RIGHT;i++)
  16. {
  17. err= pthread_create(tid+(i-LEFT),NULL,thr_prime,(void *)i);
  18. // err= pthread_create(tid+(i-LEFT),NULL,thr_prime,&i);
  19. if(err)
  20. {
  21. fprintf(stderr,"pthread_create():%sn",strerror(err));
  22. }
  23. }
  24. for(i=LEFT;i<=RIGHT;i++)
  25. {
  26. pthread_join(tid[i-LEFT],NULL);
  27. }
  28. return 0;
  29. }
  30. void* thr_prime(void*p)
  31. {
  32. int i,j,mark;
  33. i = (int)p;
  34. // i = *(int*)p;
  35. mark = 1;
  36. for(j=2;j<i/2;j++)
  37. {
  38. if(i%j ==0)
  39. {
  40. mark = 0;
  41. break;
  42. }
  43. }
  44. if(mark)
  45. printf("%d is a primer n",i);
  46. pthread_exit(NULL);
  47. return NULL;
  48. }

primer0_e.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #define LEFT 30000000
  7. #define RIGHT 30000200
  8. #define THRNUM (RIGHT-LEFT+1)
  9. struct thr_arg_st
  10. {
  11. int n;
  12. };
  13. void* thr_prime(void*p);
  14. int main()
  15. {
  16. pthread_t tid[THRNUM];
  17. int i,j,mark;
  18. int err;
  19. struct thr_arg_st* p;
  20. void *ptr;
  21. for(i =LEFT;i<=RIGHT;i++)
  22. {
  23. p = malloc(sizeof(*p));
  24. if(p ==NULL)
  25. {
  26. perror("malloc");
  27. exit(1);
  28. }
  29. p->n = i;
  30. err= pthread_create(tid+(i-LEFT),NULL,thr_prime,p); // p就是结构体指针就是n的地址
  31. // err= pthread_create(tid+(i-LEFT),NULL,thr_prime,&i);
  32. if(err)
  33. {
  34. fprintf(stderr,"pthread_create():%sn",strerror(err));
  35. }
  36. //free 不能在这里free,必须取走数据在free
  37. }
  38. for(i=LEFT;i<=RIGHT;i++)
  39. {
  40. pthread_join(tid[i-LEFT],&ptr);// 收尸并且接受返回参数。
  41. free(ptr);
  42. }
  43. return 0;
  44. }
  45. void* thr_prime(void*p)
  46. {
  47. int i,j,mark;
  48. i = ((struct thr_arg_st*)p)->n;
  49. mark = 1;
  50. for(j=2;j<i/2;j++)
  51. {
  52. if(i%j ==0)
  53. {
  54. mark = 0;
  55. break;
  56. }
  57. }
  58. if(mark)
  59. printf("%d is a primer n",i);
  60. pthread_exit(p); //返回值返回p
  61. return NULL;
  62. }
Exemplum 2

add.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #define FILENAME "/tmp/out"
  7. #define THRNUM (20)
  8. void* thr_add(void*p);
  9. int main()
  10. {
  11. pthread_t tid[THRNUM];
  12. int i,j,mark;
  13. int err;
  14. for(i =0;i<=THRNUM;i++)
  15. {
  16. err= pthread_create(tid+(i),NULL,thr_add,NULL);
  17. if(err)
  18. {
  19. fprintf(stderr,"pthread_create():%sn",strerror(err));
  20. }
  21. }
  22. for(i=0;i<=THRNUM;i++)
  23. {
  24. pthread_join(tid[i],NULL);
  25. }
  26. return 0;
  27. }
  28. void* thr_add(void*p)
  29. {
  30. FILE*fp;
  31. char line_buf[1024];
  32. int len_size = 1024;
  33. fp = fopen(FILENAME,"r+");
  34. fgets(line_buf,len_size,fp);
  35. fseek(fp,0,SEEK_SET);
  36. fprintf(fp,"%d n",atoi(line_buf)+1);
  37. fclose(fp);
  38. pthread_exit(NULL);
  39. return NULL;
  40. }

Certamen et pugnae fieri possunt cum viginti stamina data in tabella simul legere et scribere. Priusquam unum stamen scribit in, aliud stamen ultimam datam legit.

mytbf.c
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <error.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <errno.h>
  10. #include <signal.h>
  11. #include <pthread.h>
  12. #include "mytbf.h"
  13. struct mytbf_st
  14. {
  15. int cps;
  16. int burst;
  17. int token;
  18. int pos;
  19. pthread_mutex_t mut;
  20. };
  21. static pthread_mutex_t mut_job = PTHREAD_MUTEX_INITIALIZER;
  22. static pthread_t tid_alrm;
  23. pthread_once_t init_once = PTHREAD_ONCE_INIT;
  24. static struct mytbf_st* job[MYTBF_MAX];
  25. typedef void (*sighandler_t)(int);
  26. static int get_free_pos_unlocked(void)
  27. {
  28. for(int i=0;i< MYTBF_MAX;i++)
  29. {
  30. if(job[i]==NULL)
  31. return i;
  32. }
  33. return -1;
  34. }
  35. static void* thr_alrm(void*p)
  36. {
  37. while(1)
  38. {
  39. pthread_mutex_lock(&mut_job);
  40. for(int i=0;i<MYTBF_MAX;i++)
  41. {
  42. if(job[i] != NULL)
  43. {
  44. pthread_mutex_lock(&job[i]->mut);
  45. job[i]->token += job[i]->cps;
  46. if(job[i]->token >job[i]->burst )
  47. {
  48. job[i]->token = job[i]->burst;
  49. }
  50. pthread_mutex_unlock(&job[i]->mut);
  51. }
  52. }
  53. pthread_mutex_unlock(&mut_job);
  54. sleep(1);
  55. }
  56. return NULL;
  57. }
  58. static void module_unload()
  59. {
  60. pthread_cancel(tid_alrm);
  61. pthread_join(tid_alrm,NULL);
  62. //只能一个人掉,二个人调用容易出差
  63. for(int i=0;i<MYTBF_MAX;i++)
  64. {
  65. if(job[i]!=NULL)
  66. {
  67. mytbf_destroy(job[i]);
  68. }
  69. }
  70. pthread_mutex_destroy(&mut_job);
  71. }
  72. static void module_load()
  73. {
  74. int err;
  75. err = pthread_create(&tid_alrm,NULL,thr_alrm,NULL);
  76. if(err)
  77. {
  78. fprintf(stderr,"create errorn");
  79. exit(1);
  80. }
  81. atexit(module_unload);
  82. }
  83. mytbf_t* mytbf_init(int cps ,int burst) //C语言中,void*可以赋值给任何类型的指针,任何类型的指针也都可以赋值给void*
  84. {
  85. struct mytbf_st*me;
  86. int pos;
  87. pthread_once(&init_once,module_load); //只初始化一次
  88. me = malloc(sizeof(*me));
  89. if(me == NULL)
  90. return NULL;
  91. me->cps = cps;
  92. me->burst = burst;
  93. me->token = 0;
  94. pthread_mutex_init(&me->mut,NULL);
  95. pthread_mutex_lock(&mut_job);
  96. pos = get_free_pos_unlocked();
  97. if(pos < 0)
  98. {
  99. pthread_mutex_unlock(&mut_job);
  100. free(me);
  101. return NULL;
  102. }
  103. me->pos = pos;
  104. job[pos] = me;
  105. pthread_mutex_unlock(&mut_job);
  106. return me;
  107. }
  108. int mytbf_fetchtoken(mytbf_t*ptr,int size) //获取token
  109. {
  110. if(size <= 0)
  111. return -EINVAL; //参数非法
  112. struct mytbf_st*me = ptr;
  113. pthread_mutex_lock(&me->mut);
  114. while(me->token <= 0 ) //token为空就等待
  115. {
  116. pthread_mutex_unlock(&me->mut);
  117. sched_yield();
  118. pthread_mutex_lock(&me->mut);
  119. }
  120. int n = (me->token>size?size:me->token);
  121. me->token -= n;
  122. pthread_mutex_unlock(&me->mut);
  123. return n;
  124. }
  125. int mytbf_returntoken(mytbf_t*ptr,int size) //返还token
  126. {
  127. if(size<=0)
  128. return -EINVAL;
  129. struct mytbf_st*me = ptr;
  130. pthread_mutex_lock(&me->mut);
  131. me->token+= size;
  132. if(me->token > me->burst)
  133. me->token = me->burst;
  134. pthread_mutex_unlock(&me->mut);
  135. return size;
  136. }
  137. int mytbf_destroy(mytbf_t*ptr)
  138. {
  139. struct mytbf_st *me;
  140. me = ptr;
  141. pthread_mutex_lock(&mut_job);
  142. job[me->pos] = NULL;
  143. pthread_mutex_unlock(&mut_job);
  144. pthread_mutex_destroy(&me->mut);
  145. free(ptr);
  146. return 0;
  147. }

3. Post synchronisation

mutex

Aequale est seram et debet reserari antequam operari possit. (Quaestio modum)
Si homo pthread_mutex_init errorem tradit, clientelas instituere placet:
sudo facile adepto install manpages posix manpages posix-dev

int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init (pthread_mutex_t * restringere mutex,
const pthread_mutexattr_t *restringere attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int pthread_mutex_lock (pthread_mutex_t * Mutex); //
int pthread_mutex_trylock (pthread_mutex_t * Mutex); // Try ad cincinno, nisi pergere supplicium
int pthread_mutex_unlock (pthread_mutex_t * Mutex); //解锁

add.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #define FILENAME "/tmp/out"
  7. #define THRNUM (20)
  8. pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
  9. void* thr_add(void*p);
  10. int main()
  11. {
  12. pthread_t tid[THRNUM];
  13. int i,j,mark;
  14. int err;
  15. for(i =0;i<THRNUM;i++)
  16. {
  17. err= pthread_create(tid+(i),NULL,thr_add,NULL);
  18. if(err)
  19. {
  20. fprintf(stderr,"pthread_create():%sn",strerror(err));
  21. }
  22. }
  23. for(i=0;i<THRNUM;i++)
  24. {
  25. pthread_join(tid[i],NULL);
  26. }
  27. pthread_mutex_destroy(&mut);
  28. return 0;
  29. }
  30. void* thr_add(void*p)
  31. {
  32. FILE*fp;
  33. char line_buf[1024];
  34. int len_size = 1024;
  35. pthread_mutex_lock(&mut);
  36. fp = fopen(FILENAME,"r+");
  37. fgets(line_buf,len_size,fp);
  38. fseek(fp,0,SEEK_SET);
  39. fprintf(fp,"%d n",atoi(line_buf)+1);
  40. fclose(fp);
  41. pthread_mutex_unlock(&mut);
  42. pthread_exit(NULL);
  43. return NULL;
  44. }

abcd.c*

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #define FILENAME "/tmp/out"
  7. #define THRNUM (4)
  8. pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
  9. void* thr_abcd(void*p);
  10. int main()
  11. {
  12. pthread_t tid[THRNUM];
  13. int i,j,mark;
  14. int err;
  15. for(i =0;i<THRNUM;i++)
  16. {
  17. err= pthread_create(tid+(i),NULL,thr_abcd,(void*)i);
  18. if(err)
  19. {
  20. fprintf(stderr,"pthread_create():%sn",strerror(err));
  21. }
  22. }
  23. alarm(2);
  24. for(i=0;i<THRNUM;i++)
  25. {
  26. pthread_join(tid[i],NULL);
  27. }
  28. pthread_mutex_destroy(&mut);
  29. return 0;
  30. }
  31. void* thr_abcd(void*p)
  32. {
  33. int c = 'a'+ (int)p;
  34. while(1)
  35. {
  36. write(1,&c,1);
  37. }
  38. pthread_exit(NULL);
  39. return NULL;
  40. }

abcd.c*
Utere catenam cohibere ac reserare.

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #define FILENAME "/tmp/out"
  7. #define THRNUM (4)
  8. pthread_mutex_t mut[THRNUM];
  9. void* thr_abcd(void*p);
  10. int main()
  11. {
  12. pthread_t tid[THRNUM];
  13. int i,j,mark;
  14. int err;
  15. for(i =0;i<THRNUM;i++)
  16. {
  17. pthread_mutex_init(mut+i,NULL); //初始化四个锁
  18. pthread_mutex_lock(mut+i);
  19. err= pthread_create(tid+(i),NULL,thr_abcd,(void*)i);
  20. if(err)
  21. {
  22. fprintf(stderr,"pthread_create():%sn",strerror(err));
  23. }
  24. }
  25. pthread_mutex_unlock(mut+0);
  26. alarm(2);
  27. for(i=0;i<THRNUM;i++)
  28. {
  29. pthread_join(tid[i],NULL);
  30. }
  31. pthread_mutex_destroy(&mut);
  32. return 0;
  33. }
  34. int next(int n)
  35. {
  36. if(n +1 ==THRNUM)
  37. return 0;
  38. return n+1;
  39. }
  40. void* thr_abcd(void*p)
  41. {
  42. int c = 'a'+ (int)p;
  43. int n = (int)p;
  44. while(1)
  45. {
  46. pthread_mutex_lock(mut+n);
  47. write(1,&c,1);
  48. pthread_mutex_unlock(mut+next(n) );
  49. }
  50. pthread_exit(NULL);
  51. return NULL;
  52. }

Piscina algorithmus instrumentum numeri primi calculi (quaestio methodus)

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #define LEFT 30000000
  7. #define RIGHT 30000200
  8. #define THRNUM (RIGHT-LEFT+1)
  9. void* thr_prime(void*p);
  10. int main()
  11. {
  12. pthread_t tid[THRNUM];
  13. int i,j,mark;
  14. int err;
  15. for(i =LEFT;i<=RIGHT;i++)
  16. {
  17. err= pthread_create(tid+(i-LEFT),NULL,thr_prime,(void *)i);
  18. // err= pthread_create(tid+(i-LEFT),NULL,thr_prime,&i);
  19. if(err)
  20. {
  21. fprintf(stderr,"pthread_create():%sn",strerror(err));
  22. }
  23. }
  24. for(i=LEFT;i<=RIGHT;i++)
  25. {
  26. pthread_join(tid[i-LEFT],NULL);
  27. }
  28. return 0;
  29. }
  30. void* thr_prime(void*p)
  31. {
  32. int i,j,mark;
  33. i = (int)p;
  34. // i = *(int*)p;
  35. mark = 1;
  36. for(j=2;j<i/2;j++)
  37. {
  38. if(i%j ==0)
  39. {
  40. mark = 0;
  41. break;
  42. }
  43. }
  44. if(mark)
  45. printf("%d is a primer n",i);
  46. pthread_exit(NULL);
  47. return NULL;
  48. }

conditio variabilis

Notification Act communicationis.

int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_init (pthread_cond_t * restringere cond,
const pthread_condattr_t *restrict attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal (pthread_cond_t * cond); // Surge omnis insidias
int pthread_cond_timedwait (pthread_cond_t * restringere condne, // timeout insidias
pthread_mutex_t * restringere mutex,
const struct timespec *restrict abstime);
int pthread_cond_wait (pthread_cond_t * restringere cond, //死等
pthread_mutex_t *mutex restringere);

mytbf.c (notitia modum)

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <error.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <errno.h>
  10. #include <signal.h>
  11. #include <pthread.h>
  12. #include "mytbf.h"
  13. struct mytbf_st
  14. {
  15. int cps;
  16. int burst;
  17. int token;
  18. int pos;
  19. pthread_mutex_t mut;
  20. pthread_cond_t cond;
  21. };
  22. static pthread_mutex_t mut_job = PTHREAD_MUTEX_INITIALIZER;
  23. static pthread_t tid_alrm;
  24. pthread_once_t init_once = PTHREAD_ONCE_INIT;
  25. static struct mytbf_st* job[MYTBF_MAX];
  26. typedef void (*sighandler_t)(int);
  27. static int get_free_pos_unlocked(void)
  28. {
  29. for(int i=0;i< MYTBF_MAX;i++)
  30. {
  31. if(job[i]==NULL)
  32. return i;
  33. }
  34. return -1;
  35. }
  36. static void* thr_alrm(void*p)
  37. {
  38. while(1)
  39. {
  40. pthread_mutex_lock(&mut_job);
  41. for(int i=0;i<MYTBF_MAX;i++)
  42. {
  43. if(job[i] != NULL)
  44. {
  45. pthread_mutex_lock(&job[i]->mut);
  46. job[i]->token += job[i]->cps;
  47. if(job[i]->token >job[i]->burst )
  48. {
  49. job[i]->token = job[i]->burst;
  50. }
  51. pthread_cond_broadcast(&job[i]->cond);
  52. pthread_mutex_unlock(&job[i]->mut);
  53. }
  54. }
  55. pthread_mutex_unlock(&mut_job);
  56. sleep(1);
  57. }
  58. return NULL;
  59. }
  60. static void module_unload()
  61. {
  62. pthread_cancel(tid_alrm);
  63. pthread_join(tid_alrm,NULL);
  64. //只能一个人掉,二个人调用容易出差
  65. for(int i=0;i<MYTBF_MAX;i++)
  66. {
  67. if(job[i]!=NULL)
  68. {
  69. mytbf_destroy(job[i]);
  70. }
  71. }
  72. pthread_mutex_destroy(&mut_job);
  73. }
  74. static void module_load()
  75. {
  76. int err;
  77. err = pthread_create(&tid_alrm,NULL,thr_alrm,NULL);
  78. if(err)
  79. {
  80. fprintf(stderr,"create errorn");
  81. exit(1);
  82. }
  83. atexit(module_unload);
  84. }
  85. mytbf_t* mytbf_init(int cps ,int burst) //C语言中,void*可以赋值给任何类型的指针,任何类型的指针也都可以赋值给void*
  86. {
  87. struct mytbf_st*me;
  88. int pos;
  89. pthread_once(&init_once,module_load); //只初始化一次
  90. me = malloc(sizeof(*me));
  91. if(me == NULL)
  92. return NULL;
  93. me->cps = cps;
  94. me->burst = burst;
  95. me->token = 0;
  96. pthread_mutex_init(&me->mut,NULL);
  97. pthread_cond_init(&me->cond,NULL);
  98. pthread_mutex_lock(&mut_job);
  99. pos = get_free_pos_unlocked();
  100. if(pos < 0)
  101. {
  102. pthread_mutex_unlock(&mut_job);
  103. free(me);
  104. return NULL;
  105. }
  106. me->pos = pos;
  107. job[pos] = me;
  108. pthread_mutex_unlock(&mut_job);
  109. return me;
  110. }
  111. int mytbf_fetchtoken(mytbf_t*ptr,int size) //获取token
  112. {
  113. if(size <= 0)
  114. return -EINVAL; //参数非法
  115. struct mytbf_st*me = ptr;
  116. pthread_mutex_lock(&me->mut);
  117. while(me->token <= 0 ) //token为空就等待
  118. {
  119. pthread_cond_wait(&me->cond,&me->mut); //解锁等待,等待conad_broadcast和conad_signal的到来
  120. /*
  121. pthread_mutex_unlock(&me->mut);
  122. sched_yield();
  123. pthread_mutex_lock(&me->mut);
  124. */
  125. }
  126. int n = (me->token>size?size:me->token);
  127. me->token -= n;
  128. pthread_mutex_unlock(&me->mut);
  129. return n;
  130. }
  131. int mytbf_returntoken(mytbf_t*ptr,int size) //返还token
  132. {
  133. if(size<=0)
  134. return -EINVAL;
  135. struct mytbf_st*me = ptr;
  136. pthread_mutex_lock(&me->mut);
  137. me->token+= size;
  138. if(me->token > me->burst)
  139. me->token = me->burst;
  140. pthread_cond_broadcast(&me->cond);
  141. pthread_mutex_unlock(&me->mut);
  142. return size;
  143. }
  144. int mytbf_destroy(mytbf_t*ptr)
  145. {
  146. struct mytbf_st *me;
  147. me = ptr;
  148. pthread_mutex_lock(&mut_job);
  149. job[me->pos] = NULL;
  150. pthread_mutex_unlock(&mut_job);
  151. pthread_mutex_destroy(&me->mut);
  152. pthread_cond_destroy(&me->cond);
  153. free(ptr);
  154. return 0;
  155. }

primer0_pool.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #include <sched.h>
  7. #define LEFT 30000000
  8. #define RIGHT 30000200
  9. #define THRNUM (4)
  10. static int num = 0;
  11. static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
  12. static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  13. void* thr_prime(void*p);
  14. int main()
  15. {
  16. pthread_t tid[THRNUM];
  17. int i,j,mark;
  18. int err;
  19. for(i =0;i<=THRNUM;i++)
  20. {
  21. err= pthread_create(tid+(i),NULL,thr_prime,(void *)i);
  22. if(err)
  23. {
  24. fprintf(stderr,"pthread_create():%sn",strerror(err));
  25. }
  26. }
  27. //下发任务
  28. for(i=LEFT;i<RIGHT;i++)
  29. {
  30. pthread_mutex_lock(&mut);
  31. while(num !=0) //不是0就需要等待任务被取走
  32. {
  33. pthread_cond_wait(&cond,&mut);
  34. }
  35. num = i; //下发任务
  36. pthread_cond_signal(&cond); //下游叫醒任意一个
  37. pthread_mutex_unlock(&mut);
  38. }
  39. pthread_mutex_lock(&mut);
  40. while(num!= 0)
  41. {
  42. pthread_mutex_unlock(&mut);
  43. sched_yield(); //出让调度器给别的线程
  44. }
  45. num = -1; //用于线程退出
  46. pthread_cond_broadcast(&cond);
  47. pthread_mutex_unlock(&mut);
  48. for(i=0;i<=THRNUM;i++)
  49. {
  50. pthread_join(tid[i],NULL);
  51. }
  52. pthread_mutex_destroy(&mut);
  53. pthread_cond_destroy(&cond);
  54. return 0;
  55. }
  56. void* thr_prime(void*p)
  57. {
  58. int i,j,mark;
  59. while(1)
  60. {
  61. pthread_mutex_lock(&mut);
  62. while(num == 0)
  63. {
  64. pthread_cond_wait(&cond,&mut);
  65. }
  66. if(num == -1)
  67. {
  68. pthread_mutex_unlock(&mut); //走到这里必须要解锁。
  69. break;
  70. }
  71. i= num;
  72. num = 0;
  73. pthread_cond_broadcast(&cond);
  74. pthread_mutex_unlock(&mut);
  75. mark = 1;
  76. for(j=2;j<i/2;j++)
  77. {
  78. if(i%j ==0)
  79. {
  80. mark = 0;
  81. break;
  82. }
  83. }
  84. if(mark)
  85. printf("[%d]%d is a primer n",(int)p,i);
  86. }
  87. pthread_exit(NULL);
  88. return NULL;
  89. }

abcd_cond.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #define FILENAME "/tmp/out"
  7. #define THRNUM (4)
  8. pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
  9. pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  10. int num;
  11. void* thr_abcd(void*p);
  12. int main()
  13. {
  14. pthread_t tid[THRNUM];
  15. int i,j,mark;
  16. int err;
  17. for(i =0;i<THRNUM;i++)
  18. {
  19. err= pthread_create(tid+(i),NULL,thr_abcd,(void*)i);
  20. if(err)
  21. {
  22. fprintf(stderr,"pthread_create():%sn",strerror(err));
  23. }
  24. }
  25. alarm(2);
  26. for(i=0;i<THRNUM;i++)
  27. {
  28. pthread_join(tid[i],NULL);
  29. }
  30. pthread_cond_destroy(&cond);
  31. pthread_mutex_destroy(&mut);
  32. return 0;
  33. }
  34. int next(int n)
  35. {
  36. if(n +1 ==THRNUM)
  37. return 0;
  38. return n+1;
  39. }
  40. void* thr_abcd(void*p)
  41. {
  42. int c = 'a'+ (int)p;
  43. int n = (int)p;
  44. while(1)
  45. {
  46. pthread_mutex_lock(&mut);
  47. while(num != n)
  48. {
  49. pthread_cond_wait(&cond,&mut);
  50. }
  51. write(1,&c,1);
  52. num = next(num);
  53. pthread_cond_broadcast(&cond);
  54. pthread_mutex_unlock(&mut );
  55. }
  56. pthread_exit(NULL);
  57. return NULL;
  58. }

signum

Mutex est genus bool, et semaphore int.

mysem.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <pthread.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include "mysem.h"
  7. struct mysem_st
  8. {
  9. int value;
  10. pthread_mutex_t mut;
  11. pthread_cond_t cond;
  12. };
  13. mysem_t* mysem_init(int initval)
  14. {
  15. struct mysem_st*me;
  16. me = malloc(sizeof(*me));
  17. if(me==NULL)
  18. return NULL;
  19. me->value = initval;
  20. pthread_mutex_init(&me->mut,NULL);
  21. pthread_cond_init(&me->cond,NULL);
  22. return me;
  23. }
  24. int mysem_add(mysem_t*ptr ,int n)
  25. {
  26. struct mysem_st*me = ptr;
  27. pthread_mutex_lock(&me->mut);
  28. me->value+= n;
  29. pthread_cond_broadcast(&me->cond);
  30. pthread_mutex_unlock(&me->mut);
  31. return n;
  32. }
  33. int mysem_sub(mysem_t*ptr ,int n )
  34. {
  35. struct mysem_st*me = ptr;
  36. pthread_mutex_lock(&me->mut);
  37. while(me->value <n)
  38. {
  39. pthread_cond_wait(&me->cond,&me->mut);
  40. }
  41. me->value -=n;
  42. pthread_mutex_unlock(&me->mut);
  43. return n;
  44. }
  45. void mysem_destroy(mysem_t*ptr)
  46. {
  47. struct mysem_st*me = ptr;
  48. pthread_mutex_destroy(&me->mut);
  49. pthread_cond_destroy(&me->cond);
  50. free(me);
  51. }

mysem.h

  1. #ifndef MYSEM_H
  2. #define MYSEM_H
  3. typedef void mysem_t;
  4. mysem_t* mysem_init(int initval);
  5. int mysem_add(mysem_t*,int);
  6. int mysem_sub(mysem_t*,int);
  7. void mysem_destroy(mysem_t*);
  8. #endif

main.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #include "mysem.h"
  7. #define LEFT 30000000
  8. #define RIGHT 30000200
  9. #define THRNUM (RIGHT-LEFT+1)
  10. #define N 4
  11. static mysem_t* sem;
  12. void* thr_prime(void*p);
  13. int main()
  14. {
  15. pthread_t tid[THRNUM];
  16. int i,j,mark;
  17. int err;
  18. sem = mysem_init(N);
  19. if(sem ==NULL)
  20. {
  21. fprintf(stderr,"mysem_init n");
  22. exit(1);
  23. }
  24. for(i =LEFT;i<=RIGHT;i++)
  25. {
  26. mysem_sub(sem,1);
  27. err= pthread_create(tid+(i-LEFT),NULL,thr_prime,(void *)i);
  28. if(err)
  29. {
  30. fprintf(stderr,"pthread_create():%sn",strerror(err));
  31. }
  32. }
  33. for(i=LEFT;i<=RIGHT;i++)
  34. {
  35. pthread_join(tid[i-LEFT],NULL);
  36. }
  37. mysem_destroy(sem);
  38. return 0;
  39. }
  40. void* thr_prime(void*p)
  41. {
  42. int i,j,mark;
  43. i = (int)p;
  44. // i = *(int*)p;
  45. mark = 1;
  46. for(j=2;j<i/2;j++)
  47. {
  48. if(i%j ==0)
  49. {
  50. mark = 0;
  51. break;
  52. }
  53. }
  54. if(mark)
  55. printf("%d is a primer n",i);
  56. sleep(5); //ps ax -L 可以观察到对线程进行了限制,只创建了四个线程
  57. mysem_add(sem,1);
  58. pthread_exit(NULL);
  59. return NULL;
  60. }

makefile

  1. all:mysem
  2. CFLAGS+=-g -Wall -pthread
  3. LDFLAGS+= -pthread
  4. mysem:main.o mysem.o
  5. gcc $^ $(CFLAGS) $(LDFLAGS) -o $@
  6. clean:
  7. rm -rf *.o mysem

legere-scribere cincinno

Mutexum et semaphorum usum comprehensive. Divisa in lege cincinno (semaphore) et cincinno scribe (mutex). Generaliter, superior modus legendi et scribendi debet poni.

Necesse est ne scriptores fame pereant.

4. Post actis attributorum

Secundus parametri pthread_creati attributus est sequela.

int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);

Maximus numerus relatorum a programmate experimentali creatus est. ()

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <pthread.h>
  4. void* func(void)
  5. {
  6. int i;
  7. // printf("%pn",&i);
  8. pthread_exit(NULL);
  9. return NULL;
  10. }
  11. int main()
  12. {
  13. int err;
  14. pthread_t tid;
  15. pthread_attr_t attr;
  16. pthread_attr_init(&attr);
  17. pthread_attr_setstacksize(&attr,1024*1024); //1mb
  18. int i = 0;
  19. for(;;i++)
  20. {
  21. err = pthread_create(&tid,&attr,func,NULL);
  22. if(err)
  23. {
  24. fprintf(stderr,"create errn");
  25. break;
  26. }
  27. }
  28. printf("max = %d n",i);
  29. pthread_attr_destroy(&attr);
  30. return 0;
  31. }

Post synchronisation proprietatibus

Mutex possessiones;

int pthread_mutexattr_init(pthread_mutexattr_t *attr);
Refer ad pthread_mutexattr_destroy().
int pthread_mutexattr_getpshared (const pthread_mutexattr_t * attr, // operatur per processuum
int * pshared);
int pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
int pshared);

// Creare puerum processum qui tabellae descriptor ordinata communicare potest. Nulla distinctio processuum et staminum sub Linux
int clone(int (*fn)(void*), void *stack, int flags, void *arg, ...
/*pid_t *parent_tid, inanis *tls, pid_t *child_tid */ );
int pthread_mutexattr_gettype (const pthread_mutexattr_t * restringere attr,
int *restrict type);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);

Conditio variabilis possessiones:
int pthread_condattr_destroy(pthread_condattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);
Legere proprietatibus scribere, cincinno:

5. Re-introitus

Munus reentrantis est simpliciter functio quae interpellari potest. Hoc est, nempe, munus hoc quovis tempore interrumpere et in eius executione transferre ad OS scheduling ad exequendum alium codicem sine ullis erroribus cum potestate redeuntis functiones aliquas facultates systematis utuntur, ut global variabiles areas, tabulas vector interrumpunt, etc., si intermittuntur, problemata occurrere possunt.

IO in multiplicatione. Munus reserata cum extremis (munus non-reentrantis, multi- liciatorum concursus non praebetur). homo putc_reclusus, visum sine IO operatione.

Stamina et annuit

int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
int sigwait(const sigset_t *set, int *sig);
int pthread_kill(pthread_t thread, int sig);

openmp vexillum filum

Refer ad rutrum: www.OpenMp.org

Openmp syntax tags are supported after gcc4.0.Quot concursus cum paucis CPUs effici potest?

salve.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5. #pragma omp parallel //实现并发
  6. {
  7. puts("Hello ");
  8. puts(" World");
  9. }
  10. return 0;
  11. }

makefile

CFLAGS += -Wall -fopenmp

Compile salve et curre fac.

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <omp.h>
  4. int main()
  5. {
  6. #pragma omp parallel sections
  7. {
  8. #pragma omp section
  9. printf("[%d:]Hello n",omp_get_thread_num() );
  10. #pragma omp section
  11. printf("[%d:]World n",omp_get_thread_num() );
  12. }
  13. return 0;
  14. }