目录
- 创建线程
- 终止线程
- 连接已终止的进程
- 二级指针
- 线程分离
- 线程取消
- 线程属性
- 线程同步
- 多线程卖票
创建线程
编译时需要加-pthread
gcc pthread_create.c -o create -pthread
#include<pthread.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
void * callback(void * arg) {
printf("child thread...\n");
return NULL;
}
int main(){
pthread_t tid;
//创建一个子线程
int ret=pthread_create(&tid,NULL,callback,NULL);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
for(int i=0;i<5;i++){
printf("%d\n",i);
}
sleep(2);
return 0;
}
终止线程
#include<stdio.h>
#include<pthread.h>
#include<string.h>
void * callback(void * arg){
printf("child thread id:%ld\n",pthread_self());
return NULL;
}
int main(){
//创建一个子线程
pthread_t tid;
int ret=pthread_create(&tid,NULL,callback,NULL);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
//主线程
for(int i=0;i<200;i++){
printf("%d\n",i);
}
printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
//让线程退出,当主线程退出时,不会影响其他正常运行的线程
pthread_exit(NULL);
return 0;
}
主线程和子线程交替运行
连接已终止的进程
pthread_join是一个阻塞的行为,子线程没结束时不会回收的,不会执行。
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
void * callback(void * arg){
sleep(3);
printf("child thread id:%ld\n",pthread_self());
return NULL;
}
int main(){
//创建一个子线程
pthread_t tid;
int ret=pthread_create(&tid,NULL,callback,NULL);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
//主线程
for(int i=0;i<200;i++){
printf("%d\n",i);
}
printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
//主线程调用pthread_join()回收子线程的资源
ret=pthread_join(tid,NULL);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
printf("回收子线程资源成功\n");
//让线程退出,当主线程退出时,不会影响其他正常运行的线程
pthread_exit(NULL);
return 0;
}
二级指针
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
int value=10;
void * callback(void * arg){
// sleep(3);
printf("child thread id:%ld\n",pthread_self());
// int value=10;
pthread_exit((void *)&value);
// return NULL;
}
int main(){
//创建一个子线程
pthread_t tid;
int ret=pthread_create(&tid,NULL,callback,NULL);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
//主线程
for(int i=0;i<200;i++){
printf("%d\n",i);
}
printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
//主线程调用pthread_join()回收子线程的资源
int * thread_retval;
ret=pthread_join(tid,(void **)&thread_retval);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
printf("exit data:%d\n",*thread_retval);
printf("回收子线程资源成功\n");
//让线程退出,当主线程退出时,不会影响其他正常运行的线程
pthread_exit(NULL);
return 0;
}
线程分离
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
void * callback(void * arg){
printf("child thread id:%ld\n",pthread_self());
return NULL;
}
int main(){
//创建一个子进程
pthread_t tid;
int ret=pthread_create(&tid,NULL,callback,NULL);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
//输出主线程和子线程的id
printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
//设置子线程分离,子线程分离后,子线程结束时对应的资源就不需要主线程释放
pthread_detach(tid);
pthread_exit(NULL);
return 0;
}
分离之后,就不能进行连接了
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
void * callback(void * arg){
printf("child thread id:%ld\n",pthread_self());
return NULL;
}
int main(){
//创建一个子进程
pthread_t tid;
int ret=pthread_create(&tid,NULL,callback,NULL);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
//输出主线程和子线程的id
printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
//设置子线程分离,子线程分离后,子线程结束时对应的资源就不需要主线程释放
ret=pthread_detach(tid);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
//设置分离后,对分离的子线程进行连接
ret=pthread_join(tid,NULL);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
pthread_exit(NULL);
return 0;
}
线程取消
线程取消不是立马终止,而是遇到取消点的时候终止
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
void * callback(void * arg){
printf("child thread id:%ld\n",pthread_self());
for(int i=0;i<50;i++){
printf("child:%d\n",i);
}
return NULL;
}
int main(){
//创建一个子进程
pthread_t tid;
int ret=pthread_create(&tid,NULL,callback,NULL);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
//取消线程
pthread_cancel(tid);
for(int i=0;i<50;i++){
printf("%d\n",i);
}
//输出主线程和子线程的id
printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
pthread_exit(NULL);
return 0;
}
30就结束了,因为到达了取消点
线程属性
设置线程分离
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
void * callback(void * arg){
printf("child thread id:%ld\n",pthread_self());
return NULL;
}
int main(){
//创建一个线程属性变量
pthread_attr_t attr;
//初始化属性变量
pthread_attr_init(&attr);
//设置属性
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
//创建一个子进程
pthread_t tid;
int ret=pthread_create(&tid,&attr,callback,NULL);
if(ret!=0){
char * errstr=strerror(ret);
printf("error:%s\n",errstr);
}
//输出主线程和子线程的id
printf("tid:%ld,main thread id:%ld\n",tid,pthread_self());
//释放线程属性资源
pthread_attr_destroy(&attr);
pthread_exit(NULL);
return 0;
}
线程同步
多线程卖票
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
int tickets=100;//局部变量就是每个人卖100张,全局变量就是一起卖100张,所有线程共享一份资源
void * sellticket(void * arg){
//卖票
while(tickets>0){
usleep(3000);
printf("%ld 正在卖第 %d 张门票\n",pthread_self(),tickets);
tickets--;
}
return NULL;
}
int main(){
//创建3个子线程
pthread_t tid1,tid2,tid3;
pthread_create(&tid1,NULL,sellticket,NULL);
pthread_create(&tid2,NULL,sellticket,NULL);
pthread_create(&tid3,NULL,sellticket,NULL);
//回收子线程的资源,阻塞
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_join(tid3,NULL);
//设置线程分离
// pthread_detach(tid1);
// pthread_detach(tid2);
// pthread_detach(tid3);
pthread_exit(NULL);//退出主线程
return 0;
}
会产生卖同一张门票的情况
对共享数据的操作同一个时间只能一个线程
必须确保多个线程不会同时修改同一变量,或者某一线程不会读取正在由其他线程修改的变量。
这段代码的执行应该为原子操作,不能被其他线程中断
线程同步会降低效率,但是安全