1.线程的概念
2.创建线程
创建线程-----pthread_create
函数原型
成功返回0,出错返回错误号
int pthread_create(
pthread_t thread //线程id等于无符号长整型
const pthread_attr_t attr //线程属性 NULL
void (start_routine)(void)// 线程处理函数
void arg //线程处理函数参数
);
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/stat.h>
#include <unistd.h>
void* myfunc(void* arg) {
//打印子线程的ID
printf("child thread id:%lu\n",pthread_self());
return NULL;
}
int main() {
//创建一个子进程
//线程ID变量
pthread_t pthid;
pthread_create(&pthid,NULL,myfunc,NULL);
printf("parent thread id %lu\n",pthread_self());
int i=0;
for(i=0;i<5;++i) {
printf("i=%d\n",i);
}
sleep(2);
return 0;
}
循环创建多个线程
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <pthread.h>
5
6 void* myfunc(void* arc) {
7 //强制类型转换,把void*转换回int类型
E> 8 int num=(int)arc;
9 printf("id:%d child pthread id:%lu\n",num,pthread_self());
10 }
11 int main() {
12 //定义数组
13 pthread_t pth[5]={0,1,2,3,4};
14 int i=0;
15 for(i=0;i<5;++i) {
16 //为了能分辨出哪个线程是第几个创建的
17 //所以把i传递给函数,让回调函数打印出来
18 //由于cpu的时间碎片机制,对i进行传地址操作,会让序号混乱
19 //所以选择强制类型转换,对i进行传值操作
W> 20 pthread_create(&pth[i],NULL,myfunc,(void*)i);
21 }
22 sleep(3);
23 return 0;
24 }
3线程相关函数
单个线程退出函数原型
void pthread_exit(void* retval);
retval指针
阻塞等待线程退出,获取线程退出状态函数原型
int pthread_join(pathread_t thread,void**retval);
thread:要会少的子线程的线程id
retval:读取线程退出的时候携带的状态信息
//void* ptr;
//pthread_join(pthid,&ptr);
指向的内存和pthread_exit参数指向同一块内存地址
线程分离函数原型
int pthread_detach(pthread_t thread);
调用该函数后不需要pthread_join
子线程自己回收自己的pcb
杀死取消线程
int pthread_cancel(pthread_t thread);
注意事项:
在杀死的子线程对应的处理的函数的内部,必须做过一次系统调用
4线程同步
线程同步思想
互斥锁或互斥量
1.互斥锁的类型:
①创建一把锁
pthread_mutex_t mutex
②初始化互斥锁
pthread_mutex_init(
pthread_mutex_t* restrict mutex,
const pthread_mutexattr_t* restrict attr
);
③销毁互斥锁
pthread_mutex_destroy(pthread_mutex_t* mutex);
④加锁
pthread_mutex_lock(pathread_mutex_t*mutex);
⑤解锁
pthread_mutex_unlock(pthread_mutex_t*mutex);