进程是分配资源和调度执行的基本单位。
分配资源 --- 进程 (获取系统系统资源)
调度执行 --- 线程 (侧重执行任务)
pthread_create();-----------------------------------------------------------------------


线程创建好后,把tid 号存入第一个参数 thread 中
创建线程失败时,返回的是错误码,但是没有设置,因此需要手动把返回值设置为 errno
若要看线程的持续效果,则进程不能结束,线程是存在进程中的

ps -eLf 查看线程相关信息Low Weigth Process
进程号是相等的,线程变成两个

定义函数指针,用for 循环的方式创建多个线程


pthread_exit();-------------------------------------------------------------------
如果是主线程调用了 pthread_exit() ,表示主线程结束,但是,此时进程空间不销毁,直到所有的子线程都结束只有,此时进程空间销毁。
命令:time ./a.out (程序消耗的时间)

用线程实现文件拷贝:
若是子线程先结束,则反空指针,进程不退;若是主线程先结束,则调用 pthread_exit(),先退主线程,进程不退
cs
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
typedef struct pack
{
int fd_s;
int fd_d;
}pack_t;
void *do_copy(void *arg) //后一半
{
pack_t *p = arg;
off_t len = lseek(p->fd_s,0,SEEK_END);
char buf[len-len/2];
lseek(p->fd_s,len/2,SEEK_SET);
lseek(p->fd_d,len/2,SEEK_SET);
int ret = read(p->fd_s,buf,sizeof(buf));
write(p->fd_d,buf,ret);
return NULL; //若是子线程先结束,则反空指针,进程不退
}
int main(int argc, const char *argv[])
{
if (argc != 3)
{
printf("usage: %s <src> <dest>\n",argv[0]);
return -1;
}
int fd_s = open(argv[1],O_RDONLY);
int fd_d = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666);
if (fd_s < 0 || fd_d < 0)
{
perror("open fail");
return -1;
}
pack_t data = {fd_s,fd_d};
pthread_t tid;
int ret = pthread_create(&tid,NULL,do_copy, &data);
if (ret!=0)
{
errno = ret;
perror("pthread_create fail");
return -1;
}
//拷贝 后一半
off_t len = lseek(fd_s,0,SEEK_END); //可能子线程偏移量变量,所以要重新定位到开头
lseek(fd_s,0,SEEK_SET);
lseek(fd_d,0,SEEK_SET);
char buf[len/2];
ret = read(fd_s,buf,sizeof(buf));
write(fd_d,buf,ret);
close(fd_s);
close(fd_d);
pthread_exit(NULL); //若是主线程先结束,则先退主线程,进程不退
return 0;
}