Linux C 线程间同步机制

线程间同步机制

  • 概述
  • 保护机制
    • 互斥锁
      • 创建互斥锁  pthread_mutex_init
      • 加锁  pthread_mutex_lock
      • 解锁  pthread_mutex_unlock
      • 删除锁  pthread_mutex_destroy
    • 条件变量
      • 创建条件变量  pthread_cond_init
      • 激活条件变量  pthread_cond_signal
      • 等待条件变量  pthread_cond_wait
      • 删除条件变量  pthread_cond_destroy
    • 信号灯
      • 创建信号量  sem_init
      • 信号量加保护  sem_wait
      • 信号量解保护  sem_post
      • 信号量删除  sem_destroy
  • 线程间通信的例子

概述

  同进程内的所有线程共同使用进程的内存空间,并且线程可以在直接应用层完成,因此线程和线程之间的通信使用“全局变量”即可完成通信。但是由于 Linux 系统没有数据保护方式,所在在线程通信的时候需要进行数据的“同步保护”。
  在同进程中的多个线程都要操作的数据进行保护时,只允许一个线程操作要保护的内容。Linux 系统使用“信号量”、“互斥锁”以及“条件变量”来实现数据同步保护。实现数据保护的流程为:
①创建一种使用的保护机制(信号量、互斥锁或条件变量)。
②在操作保护内容之前,加保护(一旦本线程加保护成功,其他线程在操作就会阻塞)。
③在操作保护内容后,解保护(其他线程自动取消阻塞)。
④删除保护机制。
注:线程间的数据保护机制是一种人为的约束,一定要所有线程都要遵循这个操作才会有意义,同时“加保护”、“解保护”操作在一个线程中一定要成对出现。

保护机制

互斥锁

创建互斥锁  pthread_mutex_init

头文件
  #include
函数原型:int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
参数介绍:
  mutex:互斥锁编号。
  attr:互斥锁的属性。
Linux C 线程间同步机制_第1张图片
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_mutex_t mutexid;
	pthread_mutex_init(&mutexid,NULL);

加锁  pthread_mutex_lock

头文件
  #include
函数原型:int pthread_mutex_lock(pthread_mutex_t *mutex);
参数介绍:
  mutex:互斥锁编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_mutex_lock(&mutexid);

解锁  pthread_mutex_unlock

头文件
  #include
函数原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数介绍:
  mutex:互斥锁编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。
返回值:

	pthread_mutex_unlock(&mutexid);

删除锁  pthread_mutex_destroy

头文件
  #include
函数原型:int pthread_mutex_destroy(pthread_mutex_t *mutex)
参数介绍:
  mutex:互斥锁编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。
返回值:

	pthread_mutex_destroy(&mutexid);

条件变量

创建条件变量  pthread_cond_init

头文件
  #include
函数原型:int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
参数介绍:
  cond:条件变量编号。
  mutex:条件变量的属性。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_t condid;
	pthread_cond_init(&condid,NULL);

激活条件变量  pthread_cond_signal

头文件
  #include
函数原型:int pthread_cond_signal(pthread_cond_t *cond);
参数介绍:
  cond:条件变量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_signal(&condid);

等待条件变量  pthread_cond_wait

头文件
  #include
函数原型:int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
参数介绍:
  cond:条件变量编号。
  mutex:条件变量的属性。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_wait(&condid,&mutexid);

删除条件变量  pthread_cond_destroy

头文件
  #include
函数原型:int pthread_cond_destroy(pthread_cond_t *cond);
参数介绍:
  cond:条件变量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_destroy(&condid);

信号灯

创建信号量  sem_init

头文件
  #include
函数原型:==int sem_init(sem_t *sem, int pshared, unsigned int value); ==
参数介绍:
  sem:信号量编号。
  pshared:信号量在作用范围(0:本进程中多个线程共享可用;非 0:在当前登录用户的多个进程之间共享)。
  value:信号量的信号值。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_t semid;
	sem_init(&semid,0, 1);

信号量加保护  sem_wait

头文件
  #include
函数原型:int sem_wait(sem_t * sem);
参数介绍:
    sem:信号量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_wait(&semid);

信号量解保护  sem_post

头文件
  #include
函数原型:int sem_post(sem_t * sem);
参数介绍:
    sem:信号量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_post(&semid);

信号量删除  sem_destroy

头文件
  #include
函数原型:int sem_destroy(sem_t * sem);
参数介绍:
    sem:信号量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_destroy(&semid);

线程间通信的例子

Linux C 线程间同步机制_第2张图片

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
char path[10];
//信号服务函数
void * son_fun(void * arg)
{
	int fd2 = open(path,O_RDWR);		//打开读管道
	while(1)
	{
		char rb[512] = {0};
		read(fd2,rb,sizeof(rb));	
		printf("%s说:%s\n",(char *)arg,rb);	
	}
	close(fd2);							//关闭读管道
}
//关于argv:
// 1 是读通道  2 是写通道  3 是自己的信号  4 是发的信号
int main(int argc,char *argv[])
{
	//init
	pthread_t id;
	strcpy(path,argv[2]);
	//创建管道
	int val1 = mkfifo(argv[1],0666);
	int val2 = mkfifo(argv[2],0666);
	//打开管道
	int fd1 = open(argv[1],O_RDWR); 		//写管道
	//创建子线程
	pthread_create(&id,NULL,son_fun,"he say");//创建子线程
	//等待写入
	while(1)
	{
		char wb[512] = {0};
		gets(wb);
		write(fd1,wb,strlen(wb));
	}
	close(fd1);
	pthread_join(id,NULL);
	return 0;
}

你可能感兴趣的:(linux,linux,c语言,线程同步机制)