目录
1.1多线程拷贝文件
#include <head.h>
typedef struct {
const char* src;
const char* dest;
int start;
int len;
} file_t;
int GetFileLen(const char* filename)
{
int fd, len;
if ((fd = open(filename, O_RDONLY)) == -1)
PRINT_ERR("open src error");
len = lseek(fd, 0, SEEK_END);
close(fd);
return len;
}
int InitFile(const char* filename)
{
int fd;
if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1)
PRINT_ERR("open src error");
close(fd);
return 0;
}
int copy_file(const char* src, const char* dest, int start, int len)
{
int sfd, dfd, ret, count = 0;
char buf[20] = { 0 };
// 1.打开两个文件
if ((sfd = open(src, O_RDONLY)) == -1)
PRINT_ERR("open srcfile error");
if ((dfd = open(dest, O_RDWR)) == -1)
PRINT_ERR("open destfile error");
// 2.定位光标
lseek(sfd, start, SEEK_SET);
lseek(dfd, start, SEEK_SET);
// 3.循环拷贝
while (1) {
ret = read(sfd, buf, sizeof(buf));
count += ret;
if (count >= len) {
write(dfd, buf, ret - (count - len));
break;
}
write(dfd, buf, ret);
}
close(sfd);
close(dfd);
return 0;
}
void* Task(void* arg)
{
file_t *f = (file_t *)arg;
copy_file(f->src, f->dest, f->start, f->len);
pthread_exit(NULL);
}
int main(int argc, const char* argv[])
{
pthread_t tid1, tid2;
int len;
// 1.通过命令行输入源文件和目标文件
if (argc != 3) {
fprintf(stderr, "input error,try again\n");
fprintf(stderr, "usage:./a.out srcfile destfile\n");
return -1;
}
// 2.获取源文件的大小
if ((len = GetFileLen(argv[1])) == -1)
return len;
// 3.初始化目标文件
InitFile(argv[2]);
//4.初始化结构体
file_t f[] = {
[0] = {
.src = argv[1],
.dest = argv[2],
.start = 0,
.len = len / 2,
},
[1] = {
.src = argv[1],
.dest = argv[2],
.start = len / 2,
.len = len - (len / 2),
},
};
if (errno = pthread_create(&tid1, NULL, Task, (void *)&f[0]))
PRINT_ERR("pthread 1 create error");
if (errno = pthread_create(&tid2, NULL, Task, (void *)&f[1]))
PRINT_ERR("pthread 2 create error");
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
2.多线程同步互斥机制
2.1什么是同步?什么是互斥?
当多个线程同时访问临界资源的时候,竞态就产生了。解决竞态的方式可以使用线程的同步机制,
也可以使用线程的互斥机制。
互斥:是多个线程同时在争抢资源的过程,具体那个线程能够争抢到资源不确定。
同步:对对个线程的执行提前编排好顺序,在线程执行的时候按照顺序执行即可。
竞态的代码
#include <head.h>
int money = 10000;
void* Task1(void* arg)
{
while (1) {
money -= 50;
if (money >= 0) {
printf("张三取了50块钱成功,剩余=%d\n", money);
} else {
printf("余额小于50块钱\n");
pthread_exit(NULL);
}
sleep(1);
}
}
void* Task2(void* arg)
{
while (1) {
money -= 100;
if (money >= 0) {
printf("李四取了100块钱成功,剩余=%d\n", money);
} else {
printf("余额小于100块钱\n");
pthread_exit(NULL);
}
sleep(1);
}
}
int main(int argc, const char* argv[])
{
pthread_t tid1, tid2; //线程号
//创建线程1
if (errno = pthread_create(&tid1, NULL, Task1, NULL))
PRINT_ERR("pthread create error");
//创建线程2
if (errno = pthread_create(&tid2, NULL, Task2, NULL))
PRINT_ERR("pthread create error");
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
2.2线程互斥锁
线程互斥锁:线程首先要获取互斥锁,当获取互斥锁之后才能够操作临界资源,此时其他的线程获取互斥锁的时候不成功,让线程处于休眠状态。当前前面的线程解锁之后,后面的线程才有可能获取锁成功,从休眠状态重新变为运行的状态,执行临界资源的代码。以此类推...
2.2.1线程互斥锁API
#include <pthread.h>
1.定义互斥锁
pthread_mutex_t lock;
2.初始化互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//互斥锁的静态初始化
int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t * attr);
功能:互斥锁的动态初始化
参数:
@mutex:锁的变量的地址
@attr:NULL,缺省属性
功能:成功返回0,失败返回非0
3.上锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:上锁,如果获取不到锁阻塞等待
参数:
@mutex:变量的地址
返回值:成功0,失败非0
4.解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:解锁
参数:
@mutex:变量的地址
返回值:成功0,失败非0
5.销毁锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:销毁锁
参数:
@mutex:变量的地址
返回值:成功0,失败非0
2.2.2线程互斥锁的实例
#include <head.h>
// 1.定义互斥锁
pthread_mutex_t lock;
int money = 10000;
void* Task1(void* arg)
{
// 3.使用锁
while (1) {
pthread_mutex_lock(&lock);
money -= 50;
if (money >= 0) {
printf("张三取了50块钱成功,剩余=%d\n", money);
} else {
printf("余额小于50块钱\n");
pthread_mutex_unlock(&lock);
pthread_exit(NULL);
}
usleep(10000);
pthread_mutex_unlock(&lock);
}
}
void*