unix线程机制

一个程序可以包含多个进程,而一个进程又可以创建多个线程,每个线程都共享此进程的上下文环境。

在unix下使用gcc编译带有线程操作的程序时需要加上 -pthread选项。

基本的线程函数:

#include <<a target=_blank href="http://linux.die.net/include/pthread.h" rel="nofollow" style="color: rgb(102, 0, 0); text-decoration: none;"><span class="highlight" style="background-color: rgb(255, 204, 204);">pthread</span>.h</a>>

创建线程:后两个参数为待调用的函数及传递的参数

<strong>int pthread_create(pthread_t *</strong><em>thread</em><strong>, const pthread_attr_t *</strong><em>attr</em><strong>,
                   void *(*</strong><em>start_routine</em><strong>) (void *), void *</strong><em>arg</em><strong>);</strong>
在进程中等待相应线程的结束:

int pthread_join(pthread_t thread, void **retval);
 

1,创建一个能实现两数相加的线程,使用3个线程实现(a + b) * (c + d)/(e + f)。为此,我们使用一个结构体传递加数及结果:

typedef struct _Calcul { float op1, op2, result; } Calcul;

[cpp]  view plain copy
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<unistd.h>  
  4. #include<pthread.h>  
  5.   
  6. typedef struct _Calcul{ float op1, op2, result;}Calcul;  
  7. void somme(Calcul* calcul)  
  8. {  
  9.     calcul->result = calcul->op1 + calcul->op2;  
  10. }  
  11.    
  12. void main()  
  13. {  
  14.     int val_return;  
  15.     int **res1, res2, res3;  
  16.     pthread_t ptr1, ptr2, ptr3;  
  17.     Calcul calcul1, calcul2, calcul3;  
  18.     calcul1.op1=1;  
  19.     calcul1.op2=2;  
  20.     calcul2.op1=3;  
  21.         calcul2.op2=4;  
  22.     calcul3.op1=5;  
  23.         calcul3.op2=16;  
  24.   
  25.     if( (val_return=pthread_create(&ptr1, NULL, (void*)somme, (void*)(&calcul1) )) != 0)  
  26.     {     
  27.         perror("pthread_create");exit(1);  
  28.     }  
  29.     if( (val_return=pthread_create(&ptr2, NULL, (void*)somme, (void*)(&calcul2) )) != 0)  
  30.     {     
  31.         perror("pthread_create");exit(1);  
  32.     }  
  33.     if( (val_return=pthread_create(&ptr3, NULL, (void*)somme, (void*)(&calcul3) )) != 0)  
  34.     {     
  35.         perror("pthread_create");exit(1);  
  36.     }  
  37.     pthread_join( ptr1, NULL);//(void**)res1);  
  38.     pthread_join( ptr2, NULL);//(void**)res1);  
  39.     pthread_join( ptr3, NULL);//(void**)res1);  
  40.     printf("(1+2)*(3+4)/(5+16)=%f\n", calcul1.result * calcul2.result / calcul3.result);  
  41. }   

2,使用互斥(mutex)实现对共享资源的访问,涉及到的函数有:

int pthread_mutex_init(pthread_mutex_t *restrict mutex,
                                const pthread_mutexattr_t *restrict attr);

int pthread_mutex_destroy(pthread_mutex_t *mutex);

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex); 

关于互斥,在这里就不详解了。总之如果有多个线程想要访问同一个资源(比如文件)的话,那么每个线程在访问共享资源之前都应该调用pthread_mutex_lock,成功返回后就好比给共享资源加了一把锁,其他的线程在调用这个函数时会被卡住,直到此进程将资源解锁:pthread_mutex_unlock。当然init和destroy分别用于在使用前初始化和用完摧毁这一互斥。

[cpp]  view plain copy
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<errno.h>  
  4. #include<unistd.h>  
  5. #include<pthread.h>  
  6. #include <sys/types.h>  
  7. #include <sys/stat.h>  
  8. #include <fcntl.h>  
  9.   
  10. void ecrire( pthread_mutex_t * mutex)  
  11. {  
  12.     FILE* fd;  
  13.       
  14.     while(1)  
  15.     {  
  16.         pthread_mutex_lock(mutex);//c'est préférable de mettre les opération dans le corps de mutex  
  17.             //fd = open("verrou.txt", O_WRONLY | O_CREAT);  
  18.             fd = fopen("verrou.txt""w");  
  19.             if( fd==NULL ){perror("open");exit(errno);}  
  20.             fputs("Je suis la fonction ecrire!", fd);  
  21.             printf("Pthread ecrire : vient d'écrire une phrase...\n");  
  22.             fclose(fd);  
  23.         pthread_mutex_unlock(mutex);  
  24.         sleep(10);  
  25.     }  
  26. }  
  27.   
  28. void lire( pthread_mutex_t * mutex)  
  29. {  
  30.     FILE* fd;  
  31.     char msg[50];  
  32.     while(1)  
  33.     {  
  34.         pthread_mutex_lock(mutex);  
  35.             fd = fopen("verrou.txt""r");  
  36.             if( fd==NULL ){perror("open");exit(errno);}  
  37.             fgets( msg, 49, fd);  
  38.             fclose(fd);  
  39.         pthread_mutex_unlock(mutex);  
  40.         printf("Pthread lire : %s\n", msg);  
  41.         sleep(5);  
  42.     }  
  43. }  
  44.   
  45. pthread_mutex_t mutex;  
  46.   
  47.    
  48. void main()  
  49. {  
  50.     int val_return;  
  51.       
  52.     pthread_t ptr1, ptr2;  
  53.     pthread_mutex_init(&mutex, NULL);  
  54.     //mutex = PTHREAD_MUTEX_INITIALIZER;  
  55.     if( (val_return=pthread_create(&ptr1, NULL, (void*)ecrire, (void*)(&mutex) )) != 0)  
  56.     {     
  57.         perror("pthread_create");exit(1);  
  58.     }  
  59.     if( (val_return=pthread_create(&ptr2, NULL, (void*)lire, (void*)(&mutex) )) != 0)  
  60.     {     
  61.         perror("pthread_create");exit(1);  
  62.     }  
  63.       
  64.     pthread_join( ptr1, NULL);//Si le proc termine, les threads sont aussi terminés  
  65.     pthread_join( ptr2, NULL);//(void**)res1);  
  66.       
  67. }   


3,线程间的同步:barrier。

有这样一系列barrier函数可以在线程内部实现线程间的同步:

pthread_barrier_t barrier;
pthread_barrier_init(&barrier, NULL, THREAD_NUM);// Init the barrier with a number.
pthread_barrier_wait(&barrier);//The calling thread can continue only if there are THREAD_NUM threads who call this method.
pthread_barrier_destroy(&barrier);

简单地说,假如我们设置一个代表3个线程的barrier,并在3个线程中分别调用pthread_barrier_wait,那么只有当3个进程全部都执行到调用此函数的那行时,这3个线程才能继续向下进行。当第3个线程还没有到达此处时,前两个调用wait的线程都会被卡在那里,等待。


[cpp]  view plain copy
  1. /* 
  2. The barrier is a way to synchronise threads during their executions, 
  3. while pthread_join(), which is called in the body of the process, 
  4. only synchronize the end of threads. 
  5.  
  6. pthread_barrier_t barrier; 
  7. pthread_barrier_init(&barrier, NULL, THREAD_NUM);// Init the barrier with a number. 
  8. pthread_barrier_wait(&barrier);//The calling thread can continue only if there are 
  9.                 THREAD_NUM threads who call this method. 
  10. pthread_barrier_destroy(&barrier); 
  11. */  
  12.   
  13. #include<stdio.h>  
  14. #include<stdlib.h>  
  15. #include<errno.h>  
  16. #include<unistd.h>  
  17. #include<pthread.h>  
  18. #include <sys/types.h>  
  19. #include <sys/stat.h>  
  20. #include <fcntl.h>  
  21.   
  22. #define THREAD_NUM 5  
  23.   
  24. pthread_barrier_t barrier;  
  25.   
  26. void travailler( )  
  27. {  
  28.     int duree = ((int)random())%5+1;  
  29.     int threadid=pthread_self();  
  30.     printf("Pthread %d a une tâche de %d seconds.\n", threadid, duree);  
  31.     int i = 0;  
  32.     for(;i<duree;i++)  
  33.     {  
  34.         //If we put wait here, when a thread terminates, all others will be   
  35.         //suspended, because there will nerver be enough threads who call wait()  
  36.         //pthread_barrier_wait(&barrier);  
  37.         printf("Pthread %d, second %d.\n", threadid, i);  
  38.         sleep(1);  
  39.     }  
  40.     pthread_barrier_wait(&barrier);  
  41.     printf("Pthread %d termine.\n", threadid);  
  42. }  
  43.   
  44.   
  45. void main()  
  46. {  
  47.     int val_return;  
  48.     pthread_t ptrs[THREAD_NUM];  
  49.     pthread_barrier_init(&barrier, NULL, THREAD_NUM);  
  50.     int i = 0;  
  51.     for(;i<THREAD_NUM;i++)  
  52.     {  
  53.         if( (val_return=pthread_create(ptrs+i, NULL, (void*)travailler, NULL)) != 0)  
  54.         {     
  55.             perror("pthread_create");exit(1);  
  56.         }  
  57.     }  
  58.       
  59.     for(i=0;i<THREAD_NUM;i++)  
  60.     {  
  61.         pthread_join( ptrs[i], NULL);//Si le proc termine, les threads sont aussi terminés  
  62.         printf("Join thread %d .\n", i);  
  63.     }  
  64.     //pthread_barrier_destroy(&barrier);  
  65.   
  66. }   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值