线程的本质
线程可以理解为一个轻量级的进程,线程共享了栈和堆(变量),没有复制0-3G的进程空间,但线程会有自己的工作空间,会有自己的pcb块
创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
void *thread_run(void *args){
printf("I am a thread\n");
return 0;
}
int main(){
//create thread
pthread_t tid;
pthread_create(&tid,NULL,thread_run,NULL);
printf("I am a main thread\n");
return 0;
}
cmd命令:gcc thread.cpp -o thread -lpthread
退出线程
void pthread_exit(void *retval)
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
void prit(int number){
if(number==2){
pthread_exit(0);
}
printf("I am a thread!no=%d\n",number);
}
void* thread_run(void* arg){
long number=(long)arg;
prit(number);
return 0;
}
int main(){
//create thread
pthread_t tid;
for(int i=0;i<5;i++){
pthread_create(&tid,NULL,thread_run,(void*)i);
}
printf("I am a main thread\n");
return 0;
}
回收线程
int pthread_join(pthread_t thread, void **value_ptr);
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
void prit(int number){
if(number==2){
pthread_exit(NULL);
}
printf("I am a thread!no=%d\n",number);
}
void* thread_run(void* arg){
long number=(long)arg;
prit(number);
return 0;
}
int main(){
//create thread
pthread_t tid;
for(int i=0;i<5;i++){
pthread_create(&tid,NULL,thread_run,(void*)2);
}
printf("I am a main thread\n");
//linux need recycle
//等待回收
int *retval;
pthread_join(tid,(void**)&retval);
printf("retval = %d\n",retval);
return 0;
}
一般情况下需要回收线程,retval接受线程回收的返回值,tid是线程的id,该方法会阻塞等待。
但是当调用分离线程的时候,线程不会被阻塞
杀死(取消)线程
pthread_cancel(pthread_t thread)
分离线程
分离线程之后是不会等待回收,会自动回收,也就是说线程需要回收,有两种方式,一种是join一种是detach
int pthread_detach(pthread_t thread);
线程同步
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
pthread_mutex_t mutex;
int number=0;
void* thread_run(void* arg){
for(long i=0;i<20000000;i++){
//加锁
pthread_mutex_lock(&mutex);
number++;
//解锁
pthread_mutex_unlock(&mutex);
}
return 0;
}
int main(){
//初始化锁
pthread_mutex_init(&mutex,NULL);
//create thread
pthread_t tid;
int *retval;
for(int i=0;i<4;i++){
pthread_join(tid,(void**)retval);
pthread_create(&tid,NULL,thread_run,NULL);
// pthread_detach(tid);
}
sleep(5);
printf("number = %ld\n",number);
return 0;
}
生产者和消费者
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
long number = 0;
// 加一个锁
pthread_mutex_t mutex;
// 加一个条件
pthread_cond_t product_cond;
void* thread_run(void* arg){
for(long i=0; i<200000000;i++){
// 加锁
pthread_mutex_lock(&mutex);
number++;
// 解锁
pthread_mutex_unlock(&mutex);
}
return 0;
}
// 出现加锁的出错的情况,应该是没有计算完毕
// 生成者与消费者
void* consumer(void *arg){
for(;;){
pthread_mutex_lock(&mutex);
// 1. 阻塞等待唤醒
// 2. 释放锁
// 3. 被唤醒,解除阻塞,需要重新竞争锁
// 是一个 while 循环,等待有两种方式会被唤醒,一种是条件发信号,一种是系统(不正常)惊群效应
while(number <= 0){
printf("等待生产者生成产品");
pthread_cond_wait(&product_cond, &mutex);
}
printf("消费者消费产品: %ld\n",number);
number--;
// 解锁
pthread_mutex_unlock(&mutex);
sleep(1);
}
return (void*)0;
}
void* producer(void *arg){
for(;;){
pthread_mutex_lock(&mutex);
number++;
printf("生成者生产产品: %ld\n",number);
// 通知消费者消费
pthread_cond_signal(&product_cond);
// 解锁
pthread_mutex_unlock(&mutex);
sleep(1);
}
return (void*)0;
}
int main(){
// 初始化锁
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&product_cond,NULL);
pthread_t tid;
int *retval;
//for(int i=0; i<4;i++){
// 传的是同一个 id ,tid 没有赋值的,tid 是当做一个传出参数 0
pthread_create(&tid, NULL, producer, NULL);
pthread_detach(tid);
pthread_create(&tid, NULL, consumer, NULL);
pthread_detach(tid);
pthread_create(&tid, NULL, consumer, NULL);
pthread_detach(tid);
//}
while(1){
}
// sleep(5);
// 销毁锁
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&product_cond);
// 销毁条件
printf("number = %ld\n", number);
return 0;
}









网友评论