一、思路:
多线程是在一个进程中有多个线程在运行,为了实现问价读写操作,这里需要定义两个子线程,一个子线程进行读取操作,另外一个进行写入操作。
pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) //创建线程
/*参数:
thread: &tid 线程号的地址
attr: NULL 线程函数默认的属性
start_routine: 线程函数的函数名
arg: 给线程函数传递的参数 NULL
返回值:
成功: 0
失败: -1 */
int pthread_join(pthread_t thread, void **retval)//回收线程资源
/*参数:
thread: tid
返回值:
成功:0
失败: -1 */
定义一个buf用于接受读取的数据,在将buf中的数据写入待写入的文件中。
创建两个线程函数fun1,fun2;
fun1里面使用文件IO函数open,打开一个需要读取其内容的文件,赋予可读权限。使用read函数读取内容到buf中。
fun2里面使用文件IO函数open,创建一个需要写入内容的文件,赋予读写权限,文件不存在则创建该文件。使用write函数从buf中写入内容到文件中。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//打开文件,文件已经存在
int open(const char *pathname, int flags);
//创建文件,文件不存在
int open(const char *pathname, int flags, mode_t mode);
/*参数:
pathname: 文件的路径名
flags: 打开方式 O_RDONLY:只读
O_WRONLY:可写
O_RDWR:读写
O_APPEND:追加
O_TRUNC:清零
O_CREAT:创建
mode: 文件的权限 0666
返回指:
成功:文件描述符fd
失败:-1 */
#include <unistd.h>
int close(int fd);//关闭打开的文件
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);//读取内容到buf
/*参数:
fd: 文件描述符
buf: 内存地址
count: 读取的字节数 100个字节
返回值:
成功:
>0 返回实际读取到的字节数
== 0 读到文件的末尾
失败:
<0 读取失败*/
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);//从buf中写入数据到文件
/*参数:
fd: 文件描述符
buf: 内存地址
count: 写入的字节数 100个字节
返回值:
成功:返回实际写入的字节数
失败:-1 */
线程都在同时运行,由于读写有先后顺序,先读取数据,在写入数据,因此需要线程的同步或者互斥,才能保证读写的正常进行。(这里我使用的是同步)
#include <semaphore.h>
//线程的同步
sem_t sem; //信号量的变量
int sem_init(sem_t *sem, int pshared, unsigned int value);//初始化信号量
/*参数:
sem: &sem
pshared: 0:线程 1:进程
value: 初值 0 or 1
返回值:
成功:0
失败:-1 */
int sem_wait(sem_t *sem); //-1
//如果初值为0,会阻塞
int sem_post(sem_t *sem); //+1
#include <pthread.h>
//线程的互斥
pthread_mutex_t mutex; //互斥锁的变量
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);//初始化互斥锁
/*参数:
mutex: &mutex
mutexattr: NULL (默认属性)
返回值:
成功:0
失败:-1 */
int pthread_mutex_lock(pthread_mutex_t *mutex);//加锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);//解锁
二、代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
pthread_t tid1,tid2; //线程号
pthread_mutex_t mutex; //互斥锁
sem_t sem1,sem2; //信号量
char buf[20] = {0}; //接受读取文件的内容
int count = 0; //记录读取的字节数
int n = 0; //记录每次读取的字节数
/*读取子线程函数*/
void *fun1(void *arg)
{
/*以可读方式打开1.txt*/
int fd1 = open("./1.txt",O_RDONLY,0666);
if(fd1 < 0)
{
perror("open");
return (void *)-1;
}
while(1)
{
sem_wait(&sem2); // -1
//pthread_mutex_lock(&mutex); //加锁
printf("reading......!\n");
sleep(1); //延迟1s
n = read(fd1,buf,sizeof(buf)); //从1.txt中读取字符串到buf中
if(n == 0) //读到末尾结束循环
{
printf("read over!\n");
close(fd1);
//break; /*使用同步时,break后,write会阻塞,导致不能打印write over*/
/*使用互斥是需要break,结束循环*/
}
//pthread_mutex_unlock(&mutex); //解锁
sem_post(&sem1); //+1
}
}
/*写入子线程函数*/
void *fun2(void *arg)
{
/*以读写方式打开2.txt,如果文件不存在则创建2.txt*/
int fd2 = open("./2.txt",O_RDWR | O_CREAT,0666);
if(fd2 < 0)
{
perror("open");
return (void *)-1;
}
while(1)
{
sem_wait(&sem1); //-1 阻塞
printf("writing......!\n");
sleep(1);
int m =write(fd2,buf,n); // 从buf中写入字符串到fd2
if(0 == m) //写入的字节数为0时结束
{
printf("write over!\n");
close(fd2);
break;
}
count += m; //记录写入的字节数
sem_post(&sem2); //+1
}
printf("write byte:%d\n",count); //打印最终读取字节数
}
int main(int argc, char *argv[])
{
//pthread_mutex_init(&mutex,NULL); //初始化互斥锁
sem_init(&sem1,0,0); //初始化信号量
sem_init(&sem2,0,1);
/*创建子线程*/
/*fun1,读取数据的子线程*/
int ret = pthread_create(&tid1,NULL,fun1,NULL);
if(ret == -1)
{
perror("pthread_create");
return -1;
}
pthread_detach(tid1);
/*fun2,写入数据的子线程*/
ret = pthread_create(&tid2,NULL,fun2,NULL);
if(ret == -1)
{
perror("pthread_create");
return -1;
}
pthread_detach(tid2);
while(1);
return 0;
}
三、运行结果
1.txt为需要读取的文件
2.txt为写入数据前的文件(内容为空)
运行中(先读取,在写入)
读取完,写入完后的2.txt
四、完结
谢谢大家浏览!感谢!😁