题目1
定义一个全局变量,char str[] = “123456”,要求定义两个线程:线程A, 线程B
-
要求A线程循环打印全局字符串str;
-
要求B线程循环倒置全局字符串str:将str中的内容倒置为"654321",再倒置为"123456"…
注意:是倒置不是倒着打印
-
要求A线程打印出的str字符串内容为:123456或者654321。
不允许出现乱序,例如:623451 653451,,,
代码
头文件和全局变量
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<string.h>
#define PER(per) { fprintf(stderr,"line:%d ",__LINE__);\
perror(per);\
return -1;}
//全局变量
char str[]="123456";
pthread_mutex_t mutex; //定义互斥锁
倒置函数
//倒置函数
void* func(void* arg )
{
while(1)
{
pthread_mutex_lock(&mutex); //上锁
int i=strlen(str);
while(i>strlen(str)/2)
{
char temp=str[i-1];
str[i-1]=str[strlen(str)-i];
str[strlen(str)-i]=temp;
i--;
}
pthread_mutex_unlock(&mutex); //解锁
}
pthread_exit(NULL);
}
show函数
//show函数
void* show(void* arg)
{
while(1)
{
pthread_mutex_lock(&mutex); //上锁
printf("a:%s\n",str);
// sleep(1);
pthread_mutex_unlock(&mutex); //解锁
}
pthread_exit(NULL);
}
主函数
int main(int argc, const char *argv[])
{
if(pthread_mutex_init(&mutex,NULL)!=0) //创建互斥锁,并初始化
{
PER("pthread_mutex_init")
}
//创建子进程
printf("准备创建子进程\n");
pthread_t tid1,tid2;
if(pthread_create(&tid1,NULL,func,NULL)!=0) //倒置进程
{
PER("pthread_create")
}
if(pthread_create(&tid2,NULL,show,NULL)!=0) //打印进程
{
PER("pthread_create")
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_mutex_destroy(&mutex); //销毁锁
return 0;
}
题目2
- 要求用两个线程拷贝一张图片,A线程拷贝前半部分,B线程拷贝后半部分
不允许使用sleep函数,不允许使用flag
代码
头文件和全局变量
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define PER(per) { fprintf(stderr,"line:%d ",__LINE__);\
perror(per);\
return -1;}
#define PER1(per) { fprintf(stderr,"line:%d ",__LINE__);\
perror(per);\
return NULL;}
//全局变量
char str[]="123456";
pthread_mutex_t mutex; //定义互斥锁
off_t size; //文件大小
int fd;
int fd_r;
拷贝前半部分
//拷贝前半部分
void* head(void* arg )
{
pthread_mutex_lock(&mutex); //上锁
char c;
off_t x=lseek(fd,0,SEEK_SET); //回到写文件开头
if(x==(off_t)-1)
{
PER1("lseek")
}
x=lseek(fd_r,0,SEEK_SET); //回到读文件开头
if(x==(off_t)-1)
{
PER1("lseek")
}
while(1)
{
ssize_t res=read(fd_r,&c,sizeof(c));
if(res<=0)
{
if(res==0)
break;
if(res<0)
{
PER1("read")
}
}
if(write(fd,&c,sizeof(c))==EOF)
{
PER1("write")
}
x=lseek(fd_r,0,SEEK_CUR); //确认写到了哪里
if(x==(off_t)-1)
{
PER1("lseek")
}
if(x==size/2)
{
break;
}
}
pthread_mutex_unlock(&mutex); //解锁
pthread_exit(NULL);
}
拷贝后半部分
//拷贝后半部分
void* tail(void* arg)
{
pthread_mutex_lock(&mutex); //上锁
char c;
off_t x=lseek(fd,size/2,SEEK_SET);//回到文件中间
if(x==(off_t)-1)
{
PER1("lseek")
}
x=lseek(fd_r,size/2,SEEK_SET); //回到文件中间
if(x==(off_t)-1)
{
PER1("lseek")
}
while(1)
{
ssize_t res=read(fd_r,&c,sizeof(c));
if(res<=0)
{
if(res==0)
break;
if(res<0)
{
PER1("read")
}
}
if(write(fd,&c,sizeof(c))==EOF)
{
PER1("write")
}
}
pthread_mutex_unlock(&mutex); //解锁
pthread_exit(NULL);
}
主函数
int main(int argc, const char *argv[])
{
if(pthread_mutex_init(&mutex,NULL)!=0) //创建互斥锁,并初始化
{
PER("pthread_mutex_init")
}
//打开源文件,以读的方式
fd_r=open(argv[1],O_RDONLY);
if(fd_r==EOF)
{
PER("open")
}
umask(0);
//打开目标文件,以写的方式
fd=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0644);
if(fd==EOF)
{
PER("open")
}
//获取文件的大小
off_t size=lseek(fd_r,0,SEEK_END);
if(size==(off_t)-1)
{
PER("lseek")
}
//创建子进程
printf("准备创建子进程\n");
pthread_t tid1,tid2;
if(pthread_create(&tid1,NULL,head,NULL)!=0) //拷贝前半部分
{
PER("pthread_create")
}
if(pthread_create(&tid2,NULL,tail,NULL)!=0) //拷贝后半部分
{
PER("pthread_create")
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_mutex_destroy(&mutex); //销毁锁
close(fd);
close(fd_r);
return 0;
}
多线程同步与文件拷贝实践
本文通过两个示例介绍了多线程编程在字符串操作和文件拷贝中的应用。第一个例子展示了如何使用互斥锁实现线程安全的字符串倒置与打印,确保不出现乱序。第二个例子中,两个线程分别拷贝文件的前半部分和后半部分,避免使用sleep和额外标志,确保完整拷贝文件。

被折叠的 条评论
为什么被折叠?



