实验目的
- 了解线程同步原理
- 掌握线程同步的方式
实验内容
- 创建线程1,线程2
- 定义线程1线程2各自向文件中打印不同的两句话
- 对线程加入互斥锁,实现线程同步,即两个线程实现的内容不会互相打断变成乱码。
实验原理
- 线程同步指的是在互斥的基础上,实现进程之间的有序访问。
- 假设现有线程A和线程B,线程A需要往缓冲区写数据,线程B需要从缓冲区读数据,但他们之间存在一种制约关系,即当线程A写的时候,B不能来拿数据;B在拿数据的时候A不能往缓冲区写,也就是说,只有当A写完数据(或B取走数据),B才能来读数据(或A才能往里写数据)。这种关系就是一种线程的同步关系。
- 多线程编程中,难免会遇到多个线程同时访问临界资源的问题,如果不对其加以保护,那么结果肯定是不如预期的。
- 这时就出现了一种解决方法,给线程加锁,即互斥锁。
- 首先需要明确一点,互斥锁实际上是一种变量,在使用互斥锁时,实际上是对这个变量进行置0置1操作并进行判断使得线程能够获得锁或释放锁。互斥锁的作用是对临界区加以保护,以使任意时刻只有一个线程能够执行临界区的代码。实现了多线程之间的互斥。
- 此时实现线程同步就有了基础。
程序设计
#include"stdio.h"
#include"pthread.h"
#include"unistd.h"
#include"stdlib.h"
#include"string.h"
#include"sys/types.h"
#include"sys/stat.h"
#include"fcntl.h"
#define MAX_SIZE 1024
char buffer[MAX_SIZE];
struct message
{
int fd;
};
pthread_mutex_t mutex;
void *thread1(void *arg)
{
struct message msg =*((struct message *)arg);
int fd =msg.fd;
while(1)
{
pthread_mutex_lock(&mutex);
write(fd,"hello",5);
write(fd,"world\n",6);
pthread_mutex_unlock(&mutex);
}
}
void *thread2(void *arg)
{
struct message msg =*((struct message *)arg);
int fd =msg.fd;
while(1)
{
pthread_mutex_lock(&mutex);
write(fd,"hhhhh",5);
write(fd,"wwwww\n",6);
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t id1;
struct message msg;
int fd1;
int fd = open("./a.txt",O_RDWR|O_CREAT|O_APPEND,0644);
if(fd <0)
{
perror("open file error");
exit(1);
}
msg.fd = fd;
pthread_mutex_init(&mutex,NULL);
if(pthread_create(&id1,NULL,thread1,(void*)(&msg)) !=0)
{
perror("pthread creadte error!\n");
exit(1);
}
pthread_t id2;
if(pthread_create(&id2,NULL,thread2,(void*)(&msg)) !=0) {
perror("pthread creadte error!\n");
exit(1);
}
pthread_join(id1,NULL);
pthread_join(id2,NULL);
return 0;
}
运行结果
使用底行模式寻找可能会出现的乱码,并未出现。
实验总结
实现线程同步并非只有互斥锁一种方法,本次实验中尝试了互斥锁的使用,作为线程同步的方法中比较简单的一种,互斥锁更容易理解也更容易来拿来使用,当然,互斥锁也会产生死锁的问题,多种方法都能实现的话,还是不要用带锁的这个。