1.思维导图
2.互斥机制的演示
#include
char str[20];
//创建互斥锁
pthread_mutex_t mutex;
//子线程
void *task(void *arg)
{
printf("子程序:tid=%#lx\n",pthread_self());
int i=0;
while(i<10)
{
//获取锁资源
pthread_mutex_lock(&mutex);
//访问共享资源
strcpy(str,"我是ikun!");
printf("这是子线程:%s\n",str);
//销毁锁
pthread_mutex_unlock(&mutex);
i++;
}
pthread_exit(NULL);//子程序结束
}
int main(int argc, const char *argv[])
{
//创建线程
pthread_t tid;
pthread_mutex_init(&mutex,NULL);//初始化互斥锁
if(pthread_create(&tid,NULL,task,NULL)!=0)
{
printf("error\n");
return -1;
}
int i=0;
while(i<10)
{
//获取锁资源
pthread_mutex_lock(&mutex);
//访问共享资源
strcpy(str,"小黑子去死!");
printf("这是主线程:%s\n",str);
//销毁锁
pthread_mutex_unlock(&mutex);
i++;
}
pthread_join(tid,NULL);//回收子程序资源
printf("成功回收子程序!\n");
return 0;
}
3.多线程同步机制的演示
#include
char str[100];
//创建一个无名信号量、
sem_t sem;
//线程1(生产者)
void *task1(void *arg)
{
int i=0;
while(i<5)
{
strcpy(str,"ikun绝不认输");
printf("%s\n",str);
sem_post(&sem);//释放资源
sleep(1);
i++;
}
pthread_exit(NULL);
}
//线程2(消费者)
void *task2(void *arg)
{
int i=0;
while(i<5)
{
//申请资源
sem_wait(&sem);
strcpy(str,"小黑子终将被消灭");
printf("%s\n",str);
sleep(1);
i++;
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_t tid1,tid2;
//初始化同步
sem_init(&sem,0 , 0);
//创建两个线程
pthread_create(&tid1,NULL,task1,NULL);//生产者 线程1
pthread_create(&tid2,NULL,task2,NULL);//消费者 线程2
//回收
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
printf("成功回收两分支线程\n");
//销毁无名信号量
sem_destroy(&sem);
return 0;
}
4.使用3个线程完成文件的拷贝,线程1完成拷贝前一半,线程2完成拷贝后一半,主线程完成回收
#include
int fd1;
int fd2;
sem_t sem;
//拷贝的函数
void mycopy(int start,int len)
{
//将两个文件同时定位到start处
lseek(fd1, start, SEEK_SET);
lseek(fd2, start, SEEK_SET);
//循环将源文件中的len个字节拷贝到目标文件中
char buf[20] = ""; //字符搬运工
int res = 0; //每次成功读取的字符个数
int sum = 0; //记录读取字符的总个数
while(1)
{
res = read(fd1, buf, sizeof(buf));
sum += res;
if(sum >= len || res == 0)
{
write(fd2, buf, res-(sum-len));
break;
}
write(fd2, buf, res);
}
}
//线程1拷贝前一半
void *task1(void *size)
{
int start=0;
int END=(*(int *)size)/2;
mycopy(start,END);
sem_post(&sem);//释放资源
pthread_exit(NULL);
}
//线程2
void *task2(void *size)
{
sem_wait(&sem);//申请资源
int start=(*(int *)size)/2;
mycopy(start,(*(int *)size)-start);
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
if(argc!=3)
{
perror("输入格式错误");
return -1;
}
//初始化无名信号量
sem_init(&sem,0,0);
//以只读方式打开源文件
if((fd1=open(argv[1],O_RDONLY))==-1)
{
perror("fd1 open error");
return -1;
}
//以读写创建清空的方式打开目标文件
if((fd2=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0664))==-1)
{
perror("fd2,open error");
return -1;
}
int size=lseek(fd1,0,SEEK_END);
//创建两个线程
pthread_t tid1,tid2;
if(pthread_create(&tid1,NULL,task1,&size)!=0)
{
printf("error tid1\n");
return -1;
}
if(pthread_create(&tid2,NULL,task2,&size)!=0)
{
printf("error tid2\n");
return -1;
}
//回收
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
printf("复制成功,且成功回收\n");
sem_destroy(&sem);
return 0;
}
5.使用三个线程完成:线程1输出字符A,线程2输出字符B,线程3输出字符C,要求输出结果为:ABCABCABCABCABC...
#include
char str[3]="ABC";
//定义三个无名信号量
sem_t sem1;
sem_t sem2;
sem_t sem3;
void *A(void* arg)
{
int i=0;
while(i<10)
{
sem_wait(&sem3);
printf("%c",str[0]);
fflush(stdout);
i++;
sem_post(&sem1);
}
pthread_exit(NULL);
}
void *B(void* arg)
{
int i=0;
while(i<10)
{
sem_wait(&sem1);
printf("%c",str[1]);
fflush(stdout);
i++;
sem_post(&sem2);
}
pthread_exit(NULL);
}
void *C(void* arg)
{
int i=0;
while(i<10)
{
sem_wait(&sem2);
printf("%c",str[2]);
i++;
fflush(stdout);
sem_post(&sem3);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_t tid1,tid2,tid3;
//初始化无名信号量
sem_init(&sem1,0,0);
sem_init(&sem2,0,0);
sem_init(&sem3,0,1);
if(pthread_create(&tid1,NULL,A,NULL)!=0)
{
printf("error A\n");
return -1;
}
if(pthread_create(&tid2,NULL,B,NULL)!=0)
{
printf("error B\n");
return -1;
}
if(pthread_create(&tid3,NULL,C,NULL)!=0)
{
printf("error C\n");
return -1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_join(tid3,NULL);
printf("\n回收成功\n");
return 0;
}