目录
标准IO函数的时钟代码,输入quit字符串后,结束进程
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void * callback(void * arg)
{
//时间计算
time_t t2; //定义一个时间类型变量
struct tm *info = NULL;
while(1)
{
time(&t2); //保存时间戳
// printf("%ld",t2);
info = localtime(&t2); //将时间戳转换为日历信息
fprintf(stdout,"%4d-%02d-%02d %02d:%02d:%02d\n",\
info->tm_year+1900, info->tm_mon+1,info->tm_mday,\
info->tm_hour, info->tm_min, info->tm_sec);
fflush(stdout);
sleep(1);
}
return NULL;
}
int main(int argc, const char *argv[])
{
pthread_t tid;
//创建一个线程
if(pthread_create(&tid, NULL, callback, NULL) != 0)
{
fprintf(stderr, "pthread_create failed %d \n", __LINE__);
return -1;
}
char str[10] = "";
while(1)
{
scanf("%s",str);
if(strcmp(str,"quit") == 0)
{
//退出分支线程
pthread_cancel(tid);
break;
}
}
return 0;
}
要求定义-一个全变量char buf] = “1234567”,创建两个线程,不考虑退出条件。
a. A线程循环打印bu字符串,
b. B线程循环倒置bu字符串,即buf中本来存储1234567,倒置后buf中存储7654321.不抑! !
c.倒置不允许使用辅助数组。
d.要求A线程打印出来的结只能为1234567或者7654321
e.不允许使用sleep函数
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
char buf[] = "1234567";
int flag = 1;
void * str_print(void * arg) // void * arg = NULL
{
//分支线程
int len = strlen(buf);
while(1)
{
if(flag == 1)
{
printf("A线程:");
for(int i = 0; i < len; i++)
{
printf("%c",buf[i]);
}
printf("\n");
//sleep(1);
}
flag = 0;
}
return NULL;
}
void * str_rev(void * arg)
{
int len = strlen(buf);
char temp = 0;
while(1)
{
int i = 0;
int j = len - 1;
if(flag == 0)
{
while(i<j)
{
temp = buf[i];
buf[i] = buf[j];
buf[j] = temp;
i++; j--;
}
//sleep(1);
printf("===逆置后===%s\n",buf);
}
flag = 1;
}
return NULL;
}
int main(int argc, const char *argv[])
{
//创建一个线程
pthread_t tid;
if(pthread_create(&tid, NULL, str_print, NULL) != 0)
{
fprintf(stderr, "pthread_create failed %d \n", __LINE__);
return -1;
}
//创建第二个线程
pthread_t tid1;
pthread_create(&tid1, NULL, str_rev, NULL);
while(1)
{
}
return 0;
}
要求用两个线程拷贝一张图片。A线程拷贝前半部分,B线程拷后半部分,不允许使用sleep函数
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/stat.h>
int fd, fd1;
off_t size;
void * pic_copy(void * arg) // void * arg = NULL
{
//分支线程;拷贝图片的前半部分
//拷贝前半部分,修改偏移量到开头
lseek(fd, 0, SEEK_SET); //将读取文件偏移到开头
lseek(fd1, 0, SEEK_SET); //写文件偏移到开头
//复制操作
char c = 0;
for(int i = 0; i < size / 2; i++)
{
read(fd, &c, 1);
write(fd1, &c, 1);
}
printf("前半部分拷贝完成\n");
//退出线程
pthread_exit(NULL);
//return NULL;
}
int main(int argc, const char *argv[])
{
//先打开文件,需要拷贝的文件
int fd = open("./1.png",O_RDONLY);
if(fd < 0)
{
perror("open");
return -1;
}
//打开新的文件,需要拷贝到的文件
int fd1 = open("./2.png",O_WRONLY|O_CREAT|O_TRUNC,0664);
if(fd1 < 0)
{
perror("open");
return -1;
}
//大小计算,确定父子进程的偏移量/偏移位置
struct stat buf;
if(stat("./1.png",&buf) < 0)
{
perror("stat");
return -1;
}
printf("文件大小:%ld\n",buf.st_size);
off_t size = buf.st_size;
int flag = size % 2;
//创建一个线程
pthread_t tid;
if(pthread_create(&tid, NULL, pic_copy, NULL) != 0)
{
fprintf(stderr, "pthread_create failed %d \n", __LINE__);
return -1;
}
//等待分支线程结束
pthread_join(tid, NULL);
sleep(1);
//拷贝图片的后半部分
lseek(fd, size / 2, SEEK_SET);
lseek(fd1, size / 2, SEEK_SET);
char c = 0;
for(int i = 0; i < size/2+flag; i++)
{
read(fd, &c, 1);
write(fd1, &c, 1);
}
printf("后半段部分拷贝完成\n");
close(fd);
close(fd1);
return 0;
}
运行结果,复制后的图片大小相同,但是diff结果仍是不同的二进制文件,原因未找到
时隔三个月,复习过程中找到了bug所在
:变量的重复定义,全局变量和局部变量冲突后,函数存在就近原则
修改优化后的代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/stat.h>
int fd_r = 0, fd_w = 0;
void *pic_copy(void *arg) // void * arg = NULL
{
// 分支线程;拷贝图片的前半部分
// 拷贝前半部分,修改偏移量到开头
lseek(fd_r, 0, SEEK_SET); // 将读取文件偏移到开头
lseek(fd_w, 0, SEEK_SET); // 写文件偏移到开头
// 复制操作【赋值前半部分】
char c = 0;
int size_temp = *(int *)arg;
for (int i = 0; i < size_temp / 2; i++)
{
read(fd_r, &c, 1);
write(fd_w, &c, 1);
}
printf("前半部分拷贝完成\n");
// 退出线程
pthread_exit(NULL);
// return NULL; // 程序根本不会执行到这里
}
int main(int argc, const char *argv[])
{
umask(0);
// 先打开文件,需要拷贝的文件
fd_r = open("./1.png", O_RDONLY);
if (fd_r < 0)
{
perror("open");
return -1;
}
// 打开新的文件,需要拷贝到的文件
fd_w = open("./2.png", O_WRONLY | O_CREAT | O_TRUNC, 0664);
if (fd_w < 0)
{
perror("open");
return -1;
}
// 大小计算,确定父子进程的偏移量/偏移位置
struct stat buf;
if (stat("./1.png", &buf) < 0)
{
perror("stat");
return -1;
}
printf("文件大小:%ld\n", buf.st_size);
off_t size = buf.st_size; // 应该把主线程的size参数传递到分支线程中,而不是全局定义后,主线程再重复定义
off_t flag = size % 2;
// 创建一个线程
pthread_t tid;
if (pthread_create(&tid, NULL, pic_copy, &size) != 0)
{
fprintf(stderr, "pthread_create failed %d \n", __LINE__);
return -1;
}
// 等待分支线程结束
pthread_join(tid, NULL); // 阻塞函数,主线程等待分支线程的退出
// 拷贝图片的后半部分
lseek(fd_r, size / 2, SEEK_SET);
lseek(fd_w, size / 2, SEEK_SET);
char c = 0;
for (int i = 0; i < size / 2 + flag; i++)
{
read(fd_r, &c, 1);
write(fd_w, &c, 1);
}
printf("后半部分拷贝完成\n");
close(fd_r);
close(fd_w);
return 0;
}
运行结果
ubuntu@ubuntu:04-线程$ gcc 04-work3-copy.c -pthread
ubuntu@ubuntu:04-线程$ ./a.out
文件大小:498571
前半部分拷贝完成
后半部分拷贝完成
ubuntu@ubuntu:04-线程$ diff 1.png 2.png
ubuntu@ubuntu:04-线程$