1.如何创建线程
pthread_create创建线程
pthread_t t0; //保存了线程的全部信息
pthread_t t1;
if(pthread_create(&t0,NULL,does_not,NULL)== -1) //函数名为does_not
error("无法创建线程t0");
if(pthread_create(&t1,NULL,does_too,NULL)== -1) //函数名为does_too
error("无法创建线程t1");
注:线程函数的返回类型必须是void *
代码将以独立线程运行这两个函数(又产生了两个分支),如果程序(主分支)运行完这段代码,
就结束了,线程也会随之灭亡,因此必须等待线程结束(分支结束后,也结束主分支)
void *result;
if(pthread_join(t0,&result)==-1)
error("无法回收线程t0");
if(pthread_join(t1,&result)==-1)
error("无法回收线程t1");
pthread_join()会接受线程函数的返回值,并把它保存在一个void指针变量中(result)。一旦两个
线程都结束了,程序就可以顺利退出了
2.线程不安全
多线程的程序很强大,同时它们的行为也不可预测,通常当两个线程读写相同变量时,就可能相互影响结果就是不安全的。除非采
取一些控制手段。
如果想防止两个或多个线程访问共享数据资源,可以通过增设红绿灯的方式,让这些线程不能同时读取相同的数据。用来防止线程
发生车祸的红绿灯就叫互斥锁,它们是把代码变为线程安全最简单的方法。(互斥就是相互排斥的意思)
创建互斥锁
pthread_mutex_t a_lock = PTHREAD_MUTEX_INITIALIZER;
互斥锁必须对所有可能发生冲突的线程可见,因此它是一个全局变量。
PTHREAD_MUTEX_INITIALIZER 实际上是一个宏,当编译器看到它会插入创建互斥锁的代码,你需要把第一盏
红绿灯放在这段代码的开头,pthread_mutex_lock()只允许一个线程通过,其他线程运行到这行代码必须等待。
pthread_mutex_lock(&a_lock);
/*共享数据的代码*/
pthread_mutex_unlock(&a_lock);
总结:
<1>普通进程就做一件事,有了线程,进程一次就能同时做很多事。
<2>线程是"轻量级"进程。
<3>线程共享相同的全局变量。
<4>pthread_create()创建线程来运行函数
<5>pthread_join()会等待线程结束
<6>如果线程读取并更新了相同变量,代码的运行结果将不可预测。
<7>互斥锁是用来保护共享数据的锁。
<8>pthread_mutex_lock()创建互斥锁
<9>pthread_mutex_unlock()释放互斥锁。
<10>POSIX线程(pthread)是一个线程库。