一:为什么要用多线程?
- 避免阻塞:一个进程如果只有一个线程的话,当这个一个线程阻塞则就整个进程阻塞,无法再去完成其他事情。
- 提高效率,避免CPU空转:程序经常涉及读写操作就会访问磁盘,这些操作的速度比CPU慢的多,而为了等待这些操作的响应,CPU又不能去干其他的事情或者处理新的请求,导致这种单线程的程序性能差。而多线程会共享同一地址空间,线程的切换比进程快。
二:Linux提供线程同步的方式:
(一):互斥锁(mutex)
通过锁机制;同一时刻只允许一个线程执行关键部分代码。
1.初始化互斥锁
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr)
参数:
mutex:互斥锁地址,类型pthread_mutex_t
mutexattr:互斥锁的属性,通常设为NULL
也可以通过宏:PTHREAD_MUTEX_INITALIZER静态初始化互斥锁;
pthead_mutex_t mutex = PTHREAD_MUTEX_INITALIZER;
这种方式等价于指定参数 mutexattr为NULL调用pthread_mutex_init()函数。
返回值:
成功:0,成功申请的锁默打开的。
失败:非0错误码
2,上锁和解锁
int pthread_mutex_lock(pthread_mutex_t *mutex);(和阻塞)
int pthread_mutex_trylock(pthread_mutex_t *mutex);(非阻塞,得不到锁就立刻返回,并且EBUSY错误)
int pthread_mutex_unlock(pthread_mutex_t *mutex);
3,销毁锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
例子:创建两个线程,一个打印hello,一个打印world;
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
pthread_mutex_t mutex;
void printer(char* str)
{
pthread_mutex_lock(&mutex); //上锁
while(*str != '\0')
{
putchar(*str);
fflush(stdout);
++str;
sleep(1);
}
printf("\n");
pthread_mutex_unlock(&mutex); //解锁
}
void* pthread_func1(void* arg)
{
char* str = "Hello";
printer(str);
}
void* pthread_func2(void* arg)
{
char* str = "world";
printer(str);
}
int main()
{
pthread_t tid1,tid2;
pthread_mutex_init(&mutex,NULL); //初始化互斥锁
//创建两个线程
pthread_create(&tid1,NULL,pthread_func1,NULL);
pthread_create(&tid2,NULL,pthread_func2,NULL);
//等待线程结束,回收资源
pthread_join(&tid1,NULL);
pthread_join(&tid2,NULL);
//销毁互斥锁
pthread_mutex_destroy(&mutex);
return 0;
}
结果:
如果不加锁:就会乱序的打印: