1.什么是线程:线程是轻量级的进程,占用资源少,同一个进程的线程共享相同的地址空间,线程间切换时间少
2.线程概念分类:同步线程,互斥线程(防止同时修改临界资源),线程的PV操作等
3.线程相关命令 ps -eLf 查看所有线程,线程编译要链接库 -lpthread
4.线程相关函数
1)线程创建:int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
tid(出错不能用perror打印) 线程属性null 线程回调函数 给线程函数传参(可以传值,强转)
线程注意事项:①线程里面不可以写exit,否则整个进程都退出,②main函数退出,整个程序就退出,线程不存在,③线程执行完毕线程关闭,资源不回收
2)线程回收:
pthread_join函数 对应进程的 waitpid
pthread_exit 线程退出函数 对应进程的 exit,返回的值可以被pthread_join函数接受
3)线程取消: pthead_cancel 一个线程可以取消另外一个线程(不保证结果)。添加pthread_testcancel()函数保证线程可以被正常取消
4)线程的detach:int pthread_detach(pthread_t thread),设置线程为detach属性,这样线程退出资源自动释放,无需使用pthread_join(pthread_self(),自己线程tid)
5.线程相关demo代码
1)两个线程干不同是事情
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#define N 32
void *timewrite(void *arg);
void *scanfwrite(void *arg);
int main(int argc, const char *argv[])
{
pthread_t tid1,tid2;
int re1,re2;
re1 = pthread_create(&tid1,NULL,timewrite,NULL);
if(re1){
printf("pthread_create 1:%s
",strerror(re1));
return -1;
}
re2 = pthread_create(&tid2,NULL,scanfwrite,NULL);
pthread_detach(tid1);
if(re2){
printf("pthread_create 1:%s
",strerror(re2));
return -1;
}
pthread_detach(tid1);
sleep(60);
pthread_cancel(tid1);
pthread_cancel(tid2);
return 0;
}
void *timewrite(void *arg){
FILE *fp;
fp = fopen("timelog.txt", "w");
if(fp == NULL){
perror("fopen timelog");
return NULL;
}
while(1){
time_t t = time(&t);
char buf[N] ={0};
strcpy(buf,ctime(&t));
fwrite(buf,1,strlen(buf),fp);
sleep(1);
pthread_testcancel();
}
}
void *scanfwrite(void *arg){
int fd;
char buf[N]={0};
fd = open("scanflog.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666);
if(fd < 0){
perror("open scanflog");
return NULL;
}
while(1){
fgets(buf, N, stdin);
write(fd,buf,strlen(buf));
pthread_testcancel();
}
2)线程锁,防止线程同时修改临界资源区(死锁是线程相互等待各自资源,避免死锁方案①一次申请②使用一个锁)
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
pthread_mutex_t lock;
void * writefunc(void *arg){
int fd1;
char buf[32];
strcpy(buf,(char*)arg);
pthread_mutex_lock(&lock);
fd1 = open("log.txt",O_APPEND|O_WRONLY);
printf("buf = %s
",buf);
write(fd1,buf,strlen(buf));
close(fd1);
pthread_mutex_unlock(&lock);
}
int main(int argc, const char *argv[])
{
int re1,re2;
pthread_t tid1,tid2;
char *buf1 = "hello world
";
char *buf2 = "how are you
";
int fd;
pthread_mutex_init(&lock,NULL);
fd = open("log.txt", O_CREAT|O_TRUNC,0777);
if(fd<0){
perror("open");
return -1;
}
close(fd);
re1 = pthread_create(&tid1, NULL,writefunc,(void*)buf1);
if(re1){
printf("pthread_create 1:%s
",strerror(re1));
return -1;
}
pthread_detach(tid1);
re2 = pthread_create(&tid1, NULL,writefunc,(void*)buf2);
if(re2){
printf("pthread_create 1:%s
",strerror(re2));
return -1;
}
pthread_detach(tid2);
sleep(10);
return 0;
}
3)线程的PV操作(生产者消费之概念)
sem_t sem;
void * writefunc1(void *arg){
int fd1;
char buf[32];
strcpy(buf,(char*)arg);
fd1 = open("log.txt",O_APPEND|O_WRONLY);
printf("buf = %s
",buf);
write(fd1,buf,strlen(buf));
close(fd1);
// sem_post(&sem); //释放生产资源
}
void * writefunc2(void *arg){
// sem_wait(&sem); //申请消费资源
int fd1;
char buf[32];
strcpy(buf,(char*)arg);
fd1 = open("log.txt",O_APPEND|O_WRONLY);
printf("buf = %s
",buf);
write(fd1,buf,strlen(buf));
close(fd1);
}
int main(int argc, const char *argv[])
{
int re1,re2;
pthread_t tid1,tid2;
char *buf1 = "hello world
";
char *buf2 = "how are you
";
int fd;
// sem_init(&sem,0,0); //初始化生产队列
fd = open("log.txt", O_CREAT|O_TRUNC,0777);
if(fd<0){
perror("open");
return -1;
}
close(fd);
re1 = pthread_create(&tid1, NULL,writefunc1,(void*)buf1);
if(re1){
printf("pthread_create 1:%s
",strerror(re1));
return -1;
}
pthread_detach(tid1);
re2 = pthread_create(&tid1, NULL,writefunc2,(void*)buf2);
if(re2){
printf("pthread_create 1:%s
",strerror(re2));
return -1;
}
pthread_detach(tid2);
sleep(10);
return 0;
}