LINUX 线程
1、使用进程技术的优势
(1)CPU时分复用,单核心CPU可以实现宏观上的并行
(2)实现多任务系统需求(多任务的需求是客观的)
2、进程技术的劣势
(1)进程间切换开销大
(2)进程间通信麻烦而且效率低
3、解决方案就是线程技术
(1)线程技术保留了进程技术实现多任务的特性。
(2)线程的改进就是在线程间切换和线程间通信上提升了效率。
(3)多线程在多核心CPU上面更有优势。
使用线程解决键盘鼠标同时输入功能
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> int fd = -1; char buf[100]; void *func() { while(1) { memset(buf , 0, sizeof(buf)); printf("before 鼠标 \n"); read(fd , buf , 100); printf("鼠标读取的内容:[%s]\n" , buf); } } int main() { int ret = -1; pthread_t th =-1 ; fd = open("/dev/input/mouse1", O_RDONLY); if(fd < 0) { perror("open"); exit(-1); } ret = pthread_create(&th ,NULL , func , NULL);//创建线程 if(ret != 0) { printf("pthread_create error \n"); return -1; } while(1) { memset(buf , 0, sizeof(buf)); printf("before 键盘 \n"); read(0 , buf , 100); printf("键盘读取的内容:[%s]\n" , buf); } return 0; }
线程简介
(1)一种轻量级进程
(2)线程是参与内核调度的最小单元
(3)一个进程中可以有多个线程
线程技术的优势
(1)像进程一样可被OS调度
(2)同一进程的多个线程之间很容易高效率通信
(3)在多核心CPU(对称多处理器架构SMP)架构下效率最大化
线程常见函数
1、线程创建与回收
(1)pthread_create 主线程用来创造子线程的
(2)pthread_join 主线程用来等待(阻塞)回收子线程
(3)pthread_detach 主线程用来分离子线程,分离后主线程不必再去回收子线程
2、线程取消
(1)pthread_cancel 一般都是主线程调用该函数去取消(让它赶紧死)子线程
(2)pthread_setcancelstate 子线程设置自己是否允许被取消
(3)pthread_setcanceltype
3、线程函数退出相关
(1)pthread_exit与return退出
(2)pthread_cleanup_push
(3)pthread_cleanup_pop
线程同步之信号量(线程等待信号唤醒)
#include <stdio.h> #include <string.h> #include <pthread.h> #include <semaphore.h> char buf[200]; sem_t sem; int flag = 0; void *func( void * arg) { //子线程应被阻塞等待主线程激活 sem_wait(&sem); while(0==flag) { printf("本次输入了%d个字符\n",strlen(buf)); memset(buf , 0 ,sizeof(buf)); sem_wait(&sem); } pthread_exit(NULL); } int main() { pthread_t th =-1 ; int ret = -1; sem_init(&sem,0, 0); ret = pthread_create(&th ,NULL , func , NULL);//创建线程 if(ret != 0) { printf("pthread_create error \n"); return -1; } printf("输入一个字符串回车结束\n"); while(scanf("%s",buf)) { if(0==strcmp("end",buf)) { printf("程序终止\n"); flag=1; sem_post(&sem); break; } //向子线程发送信号激活 //线程的同步问题 sem_post(&sem); } printf("准备回收\n"); ret = pthread_join(th,NULL); if(ret != 0) { printf("pthread_join error \n"); return -1; } sem_destroy(&sem); printf("回收结束\n"); return 0; }
线程同步之互斥锁 (线程被上锁后其他进程无法执行,等待解锁后才能执行其他进程)
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> char buf[200]; int flag = 0; pthread_mutex_t mutex; void *func( void * arg) { //子线程应被阻塞等待主线程激活 sleep(1); while(0==flag) { pthread_mutex_lock(&mutex);//上锁 printf("本次输入了%d个字符\n",strlen(buf)); memset(buf , 0 ,sizeof(buf)); pthread_mutex_unlock(&mutex);//解锁 sleep(1); } pthread_exit(NULL); } int main() { pthread_t th =-1 ; int ret = -1; pthread_mutex_init(&mutex, NULL); ret = pthread_create(&th ,NULL , func , NULL);//创建线程 if(ret != 0) { printf("pthread_create error \n"); return -1; } printf("输入一个字符串回车结束\n"); while(1) { pthread_mutex_lock(&mutex);//上锁 scanf("%s",buf); pthread_mutex_unlock(&mutex);//解锁 if(0==strcmp("end",buf)) { printf("程序终止\n"); flag=1; break; } sleep(1); } printf("准备回收\n"); ret = pthread_join(th,NULL); if(ret != 0) { printf("pthread_join error \n"); return -1; } printf("回收结束\n"); pthread_mutex_destroy(&mutex); return 0; }
线程同步之条件变量(等待某个条件被触发)
相关函数
pthread_cond_init pthread_cond_destroy
pthread_cond_wait pthread_cond_signal/pthread_cond_broadcast
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> char buf[200]; int flag = 0; pthread_mutex_t mutex; pthread_cond_t cond; void *func( void * arg) { //子线程应被阻塞等待主线程激活 sleep(1); while(0==flag) { pthread_mutex_lock(&mutex);//上锁 pthread_cond_wait(&cond,&mutex); printf("本次输入了%d个字符\n",strlen(buf)); memset(buf , 0 ,sizeof(buf)); pthread_mutex_unlock(&mutex);//解锁 // sleep(1); } pthread_exit(NULL); } int main() { pthread_t th =-1 ; int ret = -1; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond,NULL); ret = pthread_create(&th ,NULL , func , NULL);//创建线程 if(ret != 0) { printf("pthread_create error \n"); return -1; } printf("输入一个字符串回车结束\n"); while(1) { //pthread_mutex_lock(&mutex);//上锁 scanf("%s",buf); pthread_cond_signal(&cond); //pthread_mutex_unlock(&mutex);//解锁 if(0==strcmp("end",buf)) { printf("程序终止\n"); flag=1; break; } //sleep(1); } printf("准备回收\n"); ret = pthread_join(th,NULL); if(ret != 0) { printf("pthread_join error \n"); return -1; } printf("回收结束\n"); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); return 0; }