可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 int main(){ 6 pthread_t thread_id; 7 8 thread_id=pthread_self(); // 返回调用线程的线程ID 9 printf("Thread ID: %lu.\n",thread_id); 10 11 if (pthread_equal(thread_id,pthread_self())) { 12 // if (thread_id==0) { 13 printf("Equal!\n"); 14 } else { 15 printf("Not equal!\n"); 16 } 17 return 0; 18 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 void *thrd_func(void *arg); 6 pthread_t tid; 7 8 int main(){ 9 // 创建线程tid,且线程函数由thrd_func指向,是thrd_func的入口点,即马上执行此线程函数 10 if (pthread_create(&tid,NULL,thrd_func,NULL)!=0) { 11 printf("Create thread error!\n"); 12 exit(1); 13 } 14 15 printf("TID in pthread_create function: %u.\n",tid); 16 printf("Main process: PID: %d,TID: %u.\n",getpid(),pthread_self()); 17 18 sleep(1); //race 19 20 return 0; 21 } 22 23 void *thrd_func(void *arg){ 24 // printf("I am new thread!\n"); 25 printf("New process: PID: %d,TID: %u.\n",getpid(),pthread_self()); //why pthread_self 26 printf("New process: PID: %d,TID: %u.\n",getpid(),tid); //why pthread_self 27 28 pthread_exit(NULL); //退出线程 29 // return ((void *)0); 30 }
使调用进程终止,所有线程都终止了
等待线程
•由于一个进程中的多个线程是共享数据段的,通常在线程退出之后,退出线程所占用的资源并不会随着线程的终止而得到释放
•pthread_join()函数
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 void *thrd_func1(void *arg); 6 void *thrd_func2(void *arg); 7 8 int main(){ 9 pthread_t tid1,tid2; 10 void *tret; 11 // 创建线程tid1,线程函数thrd_func1 12 if (pthread_create(&tid1,NULL,thrd_func1,NULL)!=0) { 13 printf("Create thread 1 error!\n"); 14 exit(1); 15 } 16 // 创建线程tid2,线程函数thrd_func2 17 if (pthread_create(&tid2,NULL,thrd_func2,NULL)!=0) { 18 printf("Create thread 2 error!\n"); 19 exit(1); 20 } 21 // 等待线程tid1结束,线程函数返回值放在tret中 22 if (pthread_join(tid1,&tret)!=0){ 23 printf("Join thread 1 error!\n"); 24 exit(1); 25 } 26 27 printf("Thread 1 exit code: %d.\n",(int *)tret); 28 // 等待tid2结束,线程函数返回值放在tret中 29 if (pthread_join(tid2,&tret)!=0){ 30 printf("Join thread 2 error!\n"); 31 exit(1); 32 } 33 34 printf("Thread 2 exit code: %d.\n",(int *)tret); 35 36 return 0; 37 } 38 39 void *thrd_func1(void *arg){ 40 printf("Thread 1 returning!\n"); 41 // sleep(3); 42 return ((void *)1); // 自动退出线程 43 } 44 45 void *thrd_func2(void *arg){ 46 printf("Thread 2 exiting!\n"); 47 pthread_exit((void *)2); // 线程主动退出,返回(void *)2 48 }
取消线程
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 void *thrd_func1(void *arg); 6 void *thrd_func2(void *arg); 7 8 pthread_t tid1,tid2; 9 10 int main(){ 11 // 创建线程tid1,线程函数thrd_func1 12 if (pthread_create(&tid1,NULL,thrd_func1,NULL)!=0) { 13 printf("Create thread 1 error!\n"); 14 exit(1); 15 } 16 // 创建线程tid2,线程函数thrd_func2 17 if (pthread_create(&tid2,NULL,thrd_func2,NULL)!=0) { 18 printf("Create thread 2 error!\n"); 19 exit(1); 20 } 21 // 等待线程tid1退出 22 if (pthread_join(tid1,NULL)!=0){ 23 printf("Join thread 1 error!\n"); 24 exit(1); 25 }else 26 printf("Thread 1 Joined!\n"); 27 // 等待线程tid2退出 28 if (pthread_join(tid2,NULL)!=0){ 29 printf("Join thread 2 error!\n"); 30 exit(1); 31 }else 32 printf("Thread 2 Joined!\n"); 33 34 return 0; 35 } 36 37 void *thrd_func1(void *arg){ 38 // pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); 39 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); // 设置其他线程可以cancel掉此线程 40 41 while(1) { 42 printf("Thread 1 is running!\n"); 43 sleep(1); 44 } 45 pthread_exit((void *)0); 46 } 47 48 void *thrd_func2(void *arg){ 49 printf("Thread 2 is running!\n"); 50 sleep(5); 51 if (pthread_cancel(tid1)==0) // 线程tid2向线程tid1发送cancel 52 printf("Send Cancel cmd to Thread 1.\n"); 53 54 pthread_exit((void *)0); 55 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 #define THREAD_NUM 3 6 #define REPEAT_TIMES 5 7 #define DELAY 4 8 9 void *thrd_func(void *arg); 10 11 int main(){ 12 pthread_t thread[THREAD_NUM]; 13 int no; 14 void *tret; 15 16 srand((int)time(0)); // 初始化随机函数发生器 17 18 for(no=0;no<THREAD_NUM;no++){ 19 if (pthread_create(&thread[no],NULL,thrd_func,(void*)no)!=0) { // 创建THREAD_NUM个线程,传入(void*)no作为thrd_func的参数 20 printf("Create thread %d error!\n",no); 21 exit(1); 22 } else 23 printf("Create thread %d success!\n",no); 24 } 25 26 for(no=0;no<THREAD_NUM;no++){ 27 if (pthread_join(thread[no],&tret)!=0){ // 等待thread[no]线程结束,线程函数返回值放在tret中 28 printf("Join thread %d error!\n",no); 29 exit(1); 30 }else 31 printf("Join thread %d success!\n",no); 32 } 33 34 return 0; 35 } 36 37 void *thrd_func(void *arg){ 38 int thrd_num=(void*)arg; 39 int delay_time=0; 40 int count=0; 41 42 printf("Thread %d is starting.\n",thrd_num); 43 for(count=0;count<REPEAT_TIMES;count++) { 44 delay_time=(int)(DELAY*(rand()/(double)RAND_MAX))+1; 45 sleep(delay_time); 46 printf("\tThread %d:job %d delay =%d.\n",thrd_num,count,delay_time); 47 } 48 49 printf("Thread %d is exiting.\n",thrd_num); 50 pthread_exit(NULL); 51 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 #define THREAD_NUM 3 6 #define REPEAT_TIMES 5 7 #define DELAY 4 8 9 pthread_mutex_t mutex; 10 11 void *thrd_func(void *arg); 12 13 int main(){ 14 pthread_t thread[THREAD_NUM]; 15 int no; 16 void *tret; 17 18 srand((int)time(0)); 19 // 创建快速互斥锁(默认),锁的编号返回给mutex 20 pthread_mutex_init(&mutex,NULL); 21 22 // 创建THREAD_NUM个线程,每个线程号返回给&thread[no],每个线程的入口函数均为thrd_func,参数为 23 for(no=0;no<THREAD_NUM;no++){ 24 if (pthread_create(&thread[no],NULL,thrd_func,(void*)no)!=0) { 25 printf("Create thread %d error!\n",no); 26 exit(1); 27 } else 28 printf("Create thread %d success!\n",no); 29 } 30 31 // 对每个线程进行join,返回值给tret 32 for(no=0;no<THREAD_NUM;no++){ 33 if (pthread_join(thread[no],&tret)!=0){ 34 printf("Join thread %d error!\n",no); 35 exit(1); 36 }else 37 printf("Join thread %d success!\n",no); 38 } 39 // 消除互斥锁 40 pthread_mutex_destroy(&mutex); 41 return 0; 42 } 43 44 void *thrd_func(void *arg){ 45 int thrd_num=(void*)arg; // 传入的参数,互斥锁的编号 46 int delay_time,count; 47 48 // 对互斥锁上锁 49 if(pthread_mutex_lock(&mutex)!=0) { 50 printf("Thread %d lock failed!\n",thrd_num); 51 pthread_exit(NULL); 52 } 53 54 printf("Thread %d is starting.\n",thrd_num); 55 for(count=0;count<REPEAT_TIMES;count++) { 56 delay_time=(int)(DELAY*(rand()/(double)RAND_MAX))+1; 57 sleep(delay_time); 58 printf("\tThread %d:job %d delay =%d.\n",thrd_num,count,delay_time); 59 } 60 61 printf("Thread %d is exiting.\n",thrd_num); 62 // 解锁 63 pthread_mutex_unlock(&mutex); 64 65 pthread_exit(NULL); 66 }
和上一版本的程序差异在于有没有锁,有锁的情况下,必须等"thread x is exiting."之后其他线程才能继续。
eg. 同步各线程,执行顺序为逆序。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 #include <semaphore.h> 5 6 #define THREAD_NUM 3 7 #define REPEAT_TIMES 5 8 #define DELAY 4 9 10 sem_t sem[THREAD_NUM]; 11 12 void *thrd_func(void *arg); 13 14 int main(){ 15 pthread_t thread[THREAD_NUM]; 16 int no; 17 void *tret; 18 19 srand((int)time(0)); 20 21 // 初始化THREAD_NUM-1个信号量,均初始化为0 22 for(no=0;no<THREAD_NUM-1;no++){ 23 sem_init(&sem[no],0,0); 24 } 25 26 // sem[2]信号量初始化为1,即sem数组中最后一个信号量 27 sem_init(&sem[2],0,1); 28 29 // 创建THREAD_NUM个线程,入口函数均为thrd_func,参数为(void*)no 30 for(no=0;no<THREAD_NUM;no++){ 31 if (pthread_create(&thread[no],NULL,thrd_func,(void*)no)!=0) { 32 printf("Create thread %d error!\n",no); 33 exit(1); 34 } else 35 printf("Create thread %d success!\n",no); 36 } 37 38 // 逐个join掉THREAD_NUM个线程 39 for(no=0;no<THREAD_NUM;no++){ 40 if (pthread_join(thread[no],&tret)!=0){ 41 printf("Join thread %d error!\n",no); 42 exit(1); 43 }else 44 printf("Join thread %d success!\n",no); 45 } 46 47 // 逐个取消信号量 48 for(no=0;no<THREAD_NUM;no++){ 49 sem_destroy(&sem[no]); 50 } 51 52 return 0; 53 } 54 55 void *thrd_func(void *arg){ 56 int thrd_num=(void*)arg; // 参数no 57 int delay_time,count; 58 59 // 带有阻塞的p操作 60 sem_wait(&sem[thrd_num]); 61 62 63 printf("Thread %d is starting.\n",thrd_num); 64 for(count=0;count<REPEAT_TIMES;count++) { 65 delay_time=(int)(DELAY*(rand()/(double)RAND_MAX))+1; 66 sleep(delay_time); 67 printf("\tThread %d:job %d delay =%d.\n",thrd_num,count,delay_time); 68 } 69 70 printf("Thread %d is exiting.\n",thrd_num); 71 72 // 对前一个信号量进行V操作 73 // 由于只有最后一个信号量初始化为1,其余均为0 74 // 故线程执行的顺序将为逆序 75 sem_post(&sem[(thrd_num+THREAD_NUM-1)%THREAD_NUM]); 76 77 pthread_exit(NULL); // 线程主动结束 78 }