1.线程的同步 ==>同步
======>有一定先后顺序的对资源的排他性访问。
原因:互斥锁可以控制排他访问但没有次序。
Linux下的线程同步 ===>信号量机制 ===>semaphore.h posix
信号量的分类:
1.无名信号量==》线程间通信
2.有名信号量==》进程间通信
进行线程同步的框架:
信号量的定义(sem_t sem)》信号量的初始化(sem_init())》信号量的PV操作(sem_wait(), sem_post())
==》信号量的销毁(sem_destroy()) //参数都为指针
创建线程函数第一个参数为指针,回收线程函数第参数是一个变量值(tid)
打印hello world 使用双线程,以线程同步的方式。
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
sem_t semH,semW; //定义信号量
void *th1(void *arg)
{
while(1)
{ sem_wait(&semH); //P操作
printf("hello ");
fflush(stdout);
sem_post(&semW); //V操作
}
pthread_exit(NULL);
}
void *th2(void *arg)
{
while(1)
{
sem_wait(&semW);
printf("world\n");
sleep(1);
sem_post(&semH);
}
pthread_exit(NULL);
}
int main(void)
{
//初始化信号量
sem_init(&semH, 0, 1);
sem_init(&semW, 0, 0);
//创建线程
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, th1, NULL);
pthread_create(&tid2, NULL, th2, NULL);
//回收线程
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
//销毁信号量
sem_destroy(&semH);
sem_destroy(&semW);
printf(“Hello World!\n”);
return 0;
}
模拟ATM取款 有三台机子,10个人排队
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
//定义信号量
sem_t sem_ATM;
void *th(void *arg)
{
sem_wait(&sem_ATM);
printf("get atm %lu\n", pthread_self());
sleep(rand()%5);
printf("releave atm %lu\n", pthread_self());
sem_post(&sem_ATM);
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
sem_init(&sem_ATM, 0, 3);
pthread_t tid[10];
int i = 0;
for(i = 0; i < 10; ++i)
{
pthread_create(&tid[i], NULL, th, NULL);
}
//回收线程
for(i = 0; i < 10; ++i)
{
pthread_join(tid[i], NULL);
}
//信号量销毁
sem_destroy(&sem_ATM);
return 0;
}
模拟申请空间,有三个空间,当有三个人同时使用时其他人则等待,如果一个释放则新的又获取。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
int mem[3] = {0}; //里面为0 表明有空间可以使用
sem_t sem_mem;
int mymalloc() //自定义函数
{
sem_wait(&sem_mem); //会对sem_mem减1;
int i =0;
for(i = 0; i < 3; ++i)
{
if( 0== mem[i]) //判断那个可以申请,在申请后将空间置1 表示空间不能再被使用。
{
mem[i] = 1;
return i;
}
}
}
void myfree(int id) //自定义函数
{
mem[id] = 0; //释放空间,将内容置为0表空间释放。
sem_post(&sem_mem); //会对sem_mem加1;
}
void *th(void *arg)
{
int id = mymalloc();
printf("get %d space\n", id);
sleep(rand()%5);
myfree(id);
printf("free %d \n", id);
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
int i =0;
sem_init(&sem_mem, 0, 3);
pthread_t tid[6] = {0};
for(i = 0; i < 6; ++i)
{
pthread_create(&tid[i], NULL, th, NULL);
}
for(i = 0; i < 6; ++i)
{
pthread_join(tid[i], NULL);
}
sem_destroy(&sem_mem);
return 0;
}
打印输出abc十次,使用同步线程的方式。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
/**
*打印10次abc使用多线程同步的方法 */
//定义信号量
sem_t sem_a, sem_b, sem_c;
//线程1
void *th1(void *arg)
{
int i =10;
while(i--)
{
sem_wait(&sem_a);
printf("%c\n", 'a');
sem_post(&sem_b);
}
pthread_exit(NULL);
}
//线程2
void *th2(void *arg)
{
int i =10;
while(i--)
{
sem_wait(&sem_b);
printf("%c\n", 'b');
sem_post(&sem_c);
}
pthread_exit(NULL);
}
//线程3
void *th3(void *arg)
{
int i =10;
while(i--)
{
sem_wait(&sem_c);
printf("%c\n", 'c');
sem_post(&sem_a);
}
pthread_exit(NULL);
}
int main(void)
{
//信号量的初始化
sem_init(&sem_a, 0, 1);
sem_init(&sem_b, 0, 0);
sem_init(&sem_c, 0, 0);
//创建线程
pthread_t tid1, tid2, tid3;
pthread_create(&tid1, NULL, th1, NULL);
pthread_create(&tid2, NULL, th2, NULL);
pthread_create(&tid3, NULL, th3, NULL);
//回收线程
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
//销毁信号量
sem_destroy(&sem_a);
sem_destroy(&sem_b);
sem_destroy(&sem_c);
/*int i = 0;
for(i = 0; i <3; ++i)
{
pthread_t tid[3];
pthread_create(tid[i], NULL, th, NULL);
}*/
printf("Hello World!\n");
return 0;
}
用多线程程序设计一个火车票售票系统,
要求至少有两个售票窗口,每个售票窗口
不能重复买票,将100张车票均匀的从两个
窗口卖出即可。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
/**
*模拟车站售票,卖出100张车票 */
//定义互斥锁
pthread_mutex_t mutex;
//票数变量
int ticket = 1;
//线程
void * th(void *arg)
{
pthread_mutex_lock(&mutex);
while(ticket<= 100)
{
printf("this %d ticket is %lu sale \n", ticket, pthread_self());
ticket++;
pthread_mutex_unlock(&mutex);
sleep(rand()%5);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//初始化互斥锁
pthread_mutex_init(&mutex, NULL);
//创建线程
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, th, NULL);
pthread_create(&tid2, NULL, th, NULL);
//回收线程
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
//销毁锁
pthread_mutex_destroy(&mutex);
return 0;
}