#include <iostream> #include <pthread.h> //多线程相关操作头文件 using namespace std; #define NUM_THREADS 5 //线程数 //函数返回的是函数指针,便于后面作为参数 void* say_hello(void* args) { cout << "hello..." << endl; return 0; } int main() { pthread_t tids[NUM_THREADS]; //线程id for( int i = 0; i < NUM_THREADS; ++i ) { //参数:创建的线程id,线程参数,线程运行函数的起始地址,运行函数的参数 int ret = pthread_create(&tids[i], NULL, say_hello, NULL); if( ret != 0 ) { cout << "pthread_create error:error_code=" << ret << endl; } } //等待各个线程退出后,进程才结束,否则进程强制结束,线程处于未终止的状态 pthread_exit(NULL); }
#include <iostream> #include <unistd.h> #include <pthread.h> using namespace std; class Thread{ private: static void* thread(void*);//静态函数 public: int simpleThread(); }; int Thread::simpleThread() { pthread_t id; int ret = pthread_create(&id, NULL,thread, NULL); if(ret) { cerr << "Create pthread error!" << endl; return 1; } pthread_join(id, NULL); return 0; } void* Thread::thread(void* ptr) { for(int i = 0;i < 3;i++) { sleep(1); cout << "This is a pthread." << endl; } return 0; }
#include <iostream> #include <unistd.h> #include <pthread.h> #include "Thread.h" using namespace std; int main() { Thread* newTh = new Thread(); newTh->simpleThread(); return 0; }
#include <iostream> #include <pthread.h> using namespace std; #define NUM_THREADS 5 //线程数 void* say_hello(void* args) { int i = *((int*)args); //对传入的参数进行强制类型转换,由无类型指针转变为整形指针,再用*读取其指向到内容 cout << "hello " <<i<< endl; return 0; } int main() { pthread_t tids[NUM_THREADS]; //线程id for( int i = 0; i < NUM_THREADS; ++i ) { //参数:创建的线程id,线程参数,线程运行函数的起始地址,运行函数的参数 //传入到函数的参数必须强转为void*类型,即无类型指针,&i表示取i的地址,即指向i的指针 int ret = pthread_create(&tids[i], NULL, say_hello, (void*)&i); pthread_join(tids[i], NULL); //pthread_join用来等待一个线程的结束,是一个线程阻塞的函数 if( ret != 0 ) { cout << "pthread_create error:error_code=" << ret << endl; } } //等待各个线程退出后,进程才结束,否则进程强制结束,线程处于未终止的状态 pthread_exit(NULL); }
#include <iostream> #include <pthread.h> using namespace std; #define NUM_THREADS 2 //线程数 int sum = 0; //定义全局变量,让所有线程同时写,这样就需要锁机制 pthread_mutex_t sum_mutex; //互斥锁 void* say_hello(void* args) { int i = *((int*)args); pthread_mutex_lock(&sum_mutex ); //先加锁,再修改sum的值,锁被占用就阻塞,直到拿到锁再修改sum; cout << "thread "<<i<<":before sum =" << sum <<endl; sum += i; cout << "thread "<<i<<":after sum = " << sum <<endl; pthread_mutex_unlock( &sum_mutex ); //释放锁,供其他线程使用 return 0; } int main() { pthread_t tids[NUM_THREADS]; //线程id pthread_mutex_init(&sum_mutex,NULL); for( int i = 0; i < NUM_THREADS; i++ ) { int ret = pthread_create(&tids[i], NULL, say_hello, (void*)&i); } for( int i = 0; i < NUM_THREADS; i++ ) { pthread_join(tids[i], NULL); } cout<<"finally,sum="<<sum<<endl; //等待各个线程退出后,进程才结束,否则进程强制结束,线程处于未终止的状态 pthread_exit(NULL); }
int index[NUM_THREAD];//用来保存i的值避免被修改 pthread_create(&tids[i], NULL, say_hello, (void*)&(index[i]));运行结果(改成3个线程):
#include <iostream> #include <pthread.h> using namespace std; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/ /*thread1打印10以内的偶数,thread2打印奇数*/ int i= 0; void *thread1(void *args) { for(i=0;i<=9;i++)//i是全局变量 { pthread_mutex_lock(&mutex); if(i%2==0){ cout << "thread 1,i=" << i<<endl; }else{ pthread_cond_signal(&cond);/*i变成奇数,条件改变,发送信号,通知其他线程*/ cout<<"thread 1,i="<<i<<",signal other threads"<<endl; } pthread_mutex_unlock(&mutex); } return 0; } void *thread2(void *args) { while(1) { pthread_mutex_lock(&mutex); if(i%2==0){//i是偶数线程就挂起 /*操作有2步: 第一解锁,先解除之前的pthread_mutex_lock锁定的mutex; 第二挂起,阻塞并在等待队列里休眠,即所在线程挂起,直到再次被再次唤醒*/ pthread_cond_wait(&cond,&mutex);/*wait必须和互斥锁同时用在一个线程里,它同时起到对资源的加锁和解锁*/ cout<<"pthread_cond_wait"<<endl; } cout << "thread 2,i=" << i<<endl; pthread_mutex_unlock(&mutex); } return 0; } int main() { pthread_t t_a; pthread_t t_b; pthread_create(&t_a,NULL,thread1,NULL);/*再创建进程t_a*/ pthread_create(&t_b,NULL,thread2,NULL); /*先创建进程t_b*/ pthread_join(t_a, NULL);/*等待进程t_a结束*/ pthread_join(t_b, NULL);/*等待进程t_b结束*/ pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); return 0; }运行结果(有多种运行结果):
INC = -I./include SRC = ./src FLAGE = -pthread CFLAG = -g -O3 -Wall -Wno-deprecated #-DSHOW_DEBUG #-pipe -D_NEW_LIC -D_GNU_SOURCE -D_REENTRANT -z defs CC = g++ EXE_DIR = ./bin EXE = $(EXE_DIR)/main.o \ $(EXE_DIR)/hello.o \ $(EXE_DIR)/para.o \ $(EXE_DIR)/mutex.o \ $(EXE_DIR)/signal.o \ all: $(EXE) $(EXE_DIR)/%.o:$(SRC)/%.cpp $(CC) $(CFLAG) $(FLAGE) $(INC) $< -o $@ clean: rm -rf $(EXE_DIR)/*.o rm -rf $(EXE)
总结:线程提供的同步机制是有代价,需要操作系统来调度,切换,加锁等,都是消耗资源的。
互斥量提供了对共享变量的独占式访问,条件变量允许一个或多个线程等待通知,其他线程改变了共享变量的状态。
线程的同步机制复杂,易出错,且开销比较大,所以衍生出了协程(微线程)的概念。