第一题:
使用多线程完成两个文件的拷贝,分支线程1,拷贝前一半,分支线程2拷贝后一半,主线程用于回收分支线程的资源
实现代码:
typedef struct{
int start;//读取开始位置
int len;//读多少
char src[20];
char dest[20];
}param_t;
void* task(void* argv){
param_t *p=(param_t*)argv;
printf("线程[%#lX]拷贝[%d][%d]\n",pthread_self(),p->start,p->len);
int src=open(p->src,O_RDONLY);
int dest=open(p->dest,O_WRONLY);
lseek(src,p->start,SEEK_SET);
lseek(dest,p->start,SEEK_SET);
char buf[128];
int i;
for(i=0;i+sizeof(buf) < p->len;i+=sizeof(buf)){
ssize_t cnt=read(src,buf,sizeof(buf));
write(dest,buf,cnt);
}
ssize_t cnt=read(src,buf,p->len-i);
write(dest,buf,cnt);
close(src);
close(dest);
pthread_exit(NULL);
}
int getFileSize(const char* path){
int fd=open(path, O_RDONLY);
if(fd == -1){
perror("源文件打开失败");
return -1;
}
int size=lseek(fd,0,SEEK_END)-lseek(fd,0,SEEK_SET);
close(fd);
return size;
}
int createFile(const char* path){
int fd=open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644);
if(fd == -1){
perror("目标文件打开失败");
return -1;
}
close(fd);
return 0;
}
int main(int argc, const char *argv[])
{
//读取源文件的大小
int size=getFileSize(argv[1]);
if(size == -1)
return -1;
//创建目标文件
if(createFile(argv[2]) == -1)
return -1;
//调用子线程
pthread_t t1,t2;
param_t p1={0, size/2};
strcpy(p1.src, argv[1]);
strcpy(p1.dest, argv[2]);
//
param_t p2={size/2,size-size/2};
strcpy(p2.src, argv[1]);
strcpy(p2.dest, argv[2]);
pthread_create(&t1,NULL,task,&p1);
pthread_create(&t2,NULL,task,&p2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("文件拷贝完成\n");
return 0;
}
运行效果:
ubuntu@ubuntu:~/99-Prac/1018$ ./a.out passwd 1.txt
线程[0X7F0657FBB6C0]拷贝[0][1491]
线程[0X7F06577BA6C0]拷贝[1491][1491]
文件拷贝完成
ubuntu@ubuntu:~/99-Prac/1018$ diff passwd 1.txt
第二题:互斥锁的练习 mutex
互斥锁练习。引用书《Linux_C编程一站式学习》
编写两个线程,并发执行每个线程计数5000下,总共执行10000
1、无互斥锁代码
int count=0;
void* task(void* argv){
int val;
for(int i=0;i<5000;i++){
//编写更多的费代码,给线程间切换留出更多机会
val=count;
printf("线程[%#lX],计数[%d]\n", pthread_self(),val+1);
count=val+1;
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_t t1,t2;
pthread_create(&t1,NULL,task,NULL);
pthread_create(&t2,NULL,task,NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}
2、无互斥锁运行结果
大多数的运行结果,在5000左右,而目标是10000。
3、添加互斥锁
int count=0;
pthread_mutex_t mutex;//互斥锁
void* task(void* argv){
int val;
for(int i=0;i<5000;i++){
//编写更多的费代码,给线程间切换留出更多机会
pthread_mutex_lock(&mutex);
val=count;
printf("线程[%#lX],计数[%d]\n", pthread_self(),val+1);
count=val+1;
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_mutex_init(&mutex, NULL);
pthread_t t1,t2;
pthread_create(&t1,NULL,task,NULL);
pthread_create(&t2,NULL,task,NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
4、添加互斥锁后的运行结果
10000!
第三题:信号量的练习 semaphore
线程1:生产者,每5秒生产一个产品,初始化系统有5个产品。
线程2:消费者,随机3秒内消费一个产品。
生产者-消费者模型,若无产品了,消费者需要等到生产者再进行消费。
实现代码:
sem_t sem;//信号量
int num;//库存产品的剩余数据
void getCurrentTime(char* timeStr){
time_t l=time(NULL);
struct tm* t=localtime(&l);
sprintf(timeStr,"%4d-%02d-%02d %02d:%02d:%02d",t->tm_year+1900,
t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
}
//生产者任务
void* task1(void* argv){
while(1){
num++;
sem_post(&sem);
char timeStr[20];
getCurrentTime(timeStr);
printf("%s 生产者:生产了1个产品,库存[%d]个\n", timeStr, num);
sleep(5);
}
pthread_exit(NULL);
}
//消费者任务
void* task2(void* argv){
while(1){
long t1=time(NULL);
sem_wait(&sem);
long t2=time(NULL);
num--;
char timeStr[20];
getCurrentTime(timeStr);
printf("%s 消费者:消费了1个产品,库存[%d]个.消费者等待了[%ld]秒\n",
timeStr, num,t2-t1);
sleep(rand()%4);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
sem_init(&sem, 0, 5);
num=5;
pthread_t t1,t2;
pthread_create(&t1,NULL,task1,NULL);
pthread_create(&t2,NULL,task2,NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
sem_destroy(&sem);
return 0;
}
运行效果:
ubuntu@ubuntu:~/99-Prac/1018$ ./a.out
2024-10-18 21:02:31 生产者:生产了1个产品,库存[5]个
2024-10-18 21:02:31 消费者:消费了1个产品,库存[5]个.消费者等待了[0]秒
2024-10-18 21:02:34 消费者:消费了1个产品,库存[4]个.消费者等待了[0]秒
2024-10-18 21:02:36 生产者:生产了1个产品,库存[5]个
2024-10-18 21:02:36 消费者:消费了1个产品,库存[4]个.消费者等待了[0]秒
2024-10-18 21:02:37 消费者:消费了1个产品,库存[3]个.消费者等待了[0]秒
2024-10-18 21:02:40 消费者:消费了1个产品,库存[2]个.消费者等待了[0]秒
2024-10-18 21:02:41 生产者:生产了1个产品,库存[3]个
2024-10-18 21:02:41 消费者:消费了1个产品,库存[2]个.消费者等待了[0]秒
2024-10-18 21:02:44 消费者:消费了1个产品,库存[1]个.消费者等待了[0]秒
2024-10-18 21:02:46 生产者:生产了1个产品,库存[2]个
2024-10-18 21:02:46 消费者:消费了1个产品,库存[1]个.消费者等待了[0]秒
2024-10-18 21:02:46 消费者:消费了1个产品,库存[0]个.消费者等待了[0]秒
2024-10-18 21:02:51 生产者:生产了1个产品,库存[1]个
2024-10-18 21:02:51 消费者:消费了1个产品,库存[0]个.消费者等待了[4]秒
2024-10-18 21:02:56 生产者:生产了1个产品,库存[0]个
2024-10-18 21:02:56 消费者:消费了1个产品,库存[0]个.消费者等待了[4]秒
2024-10-18 21:03:01 生产者:生产了1个产品,库存[0]个
2024-10-18 21:03:01 消费者:消费了1个产品,库存[0]个.消费者等待了[3]秒
2024-10-18 21:03:06 生产者:生产了1个产品,库存[0]个
2024-10-18 21:03:06 消费者:消费了1个产品,库存[0]个.消费者等待了[2]秒