一、 为什么要用多线程技术?
1. 避免阻塞,大家知道,单个进程只有一个主线程,当主线程阻塞的时候,整个进程也就阻塞了,无法再去做其它的一些功能了。
2. 避免CPU空转,应用程序经常会涉及到RPC,数据库访问,磁盘IO等操作,这些操作的速度比CPU慢很多,而在等待这些响应时,CPU却不能去处理新的请求,导致这种单线程的应用程序性能很差。
3. 提升效率,一个进程要独立拥有4GB的虚拟地址空间,而多个线程可以共享同一地址空间,线程的切换比进程的切换要快得多。
二、 如何使用多线程技术进行编程?
首先给一个完整的多线程程序,以下是最简单的模拟火车票售票系统:
#include<stdio.h>#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
void* ticketport1(void*);//线程函数声明
void* ticketport2(void*);//线程函数声明
int tickets=100; //火车票的起始值
int main()
{
pthread_t id1,id2;
int ret;
ret=pthread_create(&id1,NULL,ticketport1,NULL); //创建线程1
if(ret<0)
{
perror("creat thread1:");
exit(-1);
}
ret=pthread_create(&id2,NULL,ticketport2,NULL); //创建线程2
if(ret<0)
{
perror("creat thread2:");
exit(-1);
}
pthread_join(id1,NULL); //等待线程1结束
pthread_join(id2,NULL); //等待线程2结束
return 0;
}
void* ticketport1(void* arg)
{
while(1)
{
if(tickets>0)
{
//usleep(1000);
//售票点1每卖一张票,自减一
printf("ticketport1 sells ticket: %d\n",tickets--);
}
else
{
break;
}
}
return (void*)0;
}
void* ticketport2(void* arg)
{
while(1)
{
if(tickets>0)
{
//usleep(1000);
//售票点2每卖一张票,自减一
printf("ticketport2 sells ticket: %d\n",tickets--);
}
else
{
break;
}
}
return (void*)0;
}
我们用pthread_create函数来创建线程,用pthread_join来阻塞主线程,等待子线程执行完成后返回。利用了多线程技术来创建了两个售票点,可以不同的地方进行同时售票。三、 使用多线程的同步与互斥
1、多线程的同步方式有很多种,例如互斥锁,条件变量,信号量,读写锁。先看看互斥锁如何解决多线程之间的同步问题。程序用互斥锁后如下:
#include<stdio.h>
#include<pthread.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
void* ticketport1(void*);
void* ticketport2(void*);
int tickets=100;
pthread_mutex_t mutex;
int main()
{
int ret;
pthread_t id1,id2;
pthread_mutex_init(&mutex,NULL); //初始化互斥量
ret=pthread_create(&id1,NULL,ticketport1,NULL);
if(ret<0)
{
perror("creat thread1:");
exit(-1);
}
ret=pthread_create(&id2,NULL,ticketport2,NULL);
if(ret<0)
{
perror("creat thread2:");
exit(-1);
}
pthread_join(id1,NULL);
pthread_join(id2,NULL);
}
void* ticketport1(void* arg)
{
while(1)
{
pthread_mutex_lock(&mutex); //给互斥量上锁
if(tickets>0)
{
usleep(1000);
printf("thread1 sell ticket: %d\n",tickets--);
pthread_mutex_unlock(&mutex); //给互斥量解锁
}
else
{
pthread_mutex_unlock(&mutex); //给互斥量解锁
break;
}
pthread_yield(); //线程的调度函数,使两个线程都有执行机会
}
return (void*)0;
}
void* ticketport2(void* arg)
{
while(1)
{
pthread_mutex_lock(&mutex); //给互斥量上锁
if(tickets>0)
{
usleep(1000);
printf("thread2 sell ticket: %d\n",tickets--);
pthread_mutex_unlock(&mutex); //给互斥量解锁
}
else
{
pthread_mutex_unlock(&mutex); //给互斥量解锁
break;
}
pthread_yield(); //线程的调度函数,使两个线程都有执行机会
}
return (void*)0;
}
我们用pthread_mutext_init函数来初始化互斥量,然后再用pthread_mutex_lock函数和pthread_mutext_unlock分别进行上锁和解锁,至于这两个函数的参数说明,大家可以上网查阅,在这我只说明功能。我们用gcc带选项-lpthread编译后多次执行发现即使强制线程在很短的时间内(如1ms)睡眠引起线程切换,也不会导致上述的问题,说明互斥锁可以解决线程间的同步问题。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |