linux线程之间的通信

线程之间的通信:

1、  互斥量

用的api函数有:pthread_mutex_init、pthread_mutex_lock、pthread_mutex_unlock、pthread_mutex_trylock

示例:

//thread_mutex.cpp

#include <iostream>
#include<queue>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include<signal.h>
using namespace std;

typedef unsigned int u32;
typedef unsigned char byte;
bool flag_exit = false;
char *data ="test pthread mutex!";

typedef struct job
{
	u32 id;
	u32 len;
	byte data[1];
}JOB,*PJOB;

queue<PJOB> g_thrd_queue;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

typedef void (*sighandler_t)(int);

void handlesignal(int signal)
{
	cout << "+++handlesignal+++" << endl;
	flag_exit = true;
}

PJOB packjob(u32 id,byte *pdata,u32 len )
{
	PJOB pret = NULL;
	int size = sizeof(JOB) + len;
	pret = (PJOB)malloc(size);
	if(pret != NULL)
	{
		memset(pret,0,size);
		pret->id = id;
		pret->len = size;
		memcpy(pret->data,pdata,len);
	}
	return pret;
}

typedef void* (*pthrd_fun)(void*);

void * thrd_function_1(void *parg)
{
	int iexit;
	PJOB pjob;
	int count = 0;
	cout << "thrd id is:  " << pthread_self() << " run..." << endl;
	while(!flag_exit)
	{
		pjob = packjob(count++,(byte*)data,strlen(data));
		//锁定互斥体
		pthread_mutex_lock(&mutex);

		g_thrd_queue.push(pjob);
		//解除互斥体
		pthread_mutex_unlock(&mutex);

		//睡眠2秒中
		sleep(1);
		
	}

	cout << "thrd id is:  " << pthread_self() << " exit!" << endl;
	iexit = 0;
	pthread_exit(&iexit);
}

void * thrd_function_2(void *parg)
{
	int iexit;
	PJOB pjob;
	cout << "thrd id is:  " << pthread_self() << " run..." << endl;
	while(!flag_exit)
	{
		//锁定互斥体
		pthread_mutex_lock(&mutex);

		pjob = g_thrd_queue.front();
		g_thrd_queue.pop();
		//解除互斥体
		pthread_mutex_unlock(&mutex);

		cout << "id :"<<pjob->id << endl;
		cout <<"len :"<< pjob->len << endl;
		cout <<"data :" << (char*) pjob->data << endl;

		//释放内存
		free(pjob);

		//睡眠2秒中
		sleep(1);
	}

	cout << "thrd id is:  " << pthread_self() << " exit!" << endl;
	iexit = 0;
	pthread_exit(&iexit);
}

int main(int argc,char *argv[])
{
	pthread_t thread_id1;
	pthread_t thread_id2;
	int iret;
	
	cout << "pid id is:  " << getpid() << endl;

	//安置信号处理函数
	signal(SIGUSR1,handlesignal);
	
	iret = pthread_create(&thread_id1,NULL,thrd_function_1,NULL);
	if(iret != 0)
	{
		iret = 1;
	}

	iret = pthread_create(&thread_id2,NULL,thrd_function_2,NULL);
	if(iret != 0)
	{
		iret = 1;
	}

	//等待子线程的退出
	pthread_join(thread_id1,NULL);
	pthread_join(thread_id2,NULL);

	//释放内存
	while(!g_thrd_queue.empty())
	{
		PJOB pjob;
		pjob = g_thrd_queue.front();
		g_thrd_queue.pop();

		free(pjob);
	}
	cout << "main thread is exit!" << endl;
	return iret;
}

注意:有时候我们需要检测一个互斥体的状态却不希望被阻塞,那么我们就可以pthread_mutex_trylock。当你对一个解锁状态的互斥体调用pthread_mutex_trylock 时,就如调用pthread_mutex_lock 一样会锁定这个互斥体;pthread_mutex_trylock 会返回 0。 而当互斥体已经被其它线程锁定的时候,pthread_mutex_trylock 不会阻塞。相应的,pthread_mutex_trylock 会返回错误码EBUSY。持有锁的其它线程不会受到影响。你可以稍后再次尝试锁定这个互斥体

2、 信号量

用的api函数有:sem_init、sem_wait、sem_post、sem_destory、sem_trywait

示例:

#include<iostream>
#include<queue>
//thread_sem.cc

#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<signal.h>
#include<semaphore.h>

using namespace std;

typedef unsigned int u32;
typedef unsigned char byte;
bool flag_exit = false;
char *data ="test pthread mutex!";


typedef struct job
{
	u32 id;
	u32 len;
	byte data[1];
}JOB,*PJOB;

queue<PJOB> g_thrd_queue;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

sem_t sem_job_count;

typedef void (*sighandler_t)(int);

void handlesignal(int signal)
{
	cout << "+++handlesignal+++" << endl;
	flag_exit = true;
}

PJOB packjob(u32 id,byte *pdata,u32 len )
{
	PJOB pret = NULL;
	int size = sizeof(JOB) + len;
	pret = (PJOB)malloc(size);
	if(pret != NULL)
	{
		memset(pret,0,size);
		pret->id = id;
		pret->len = size;
		memcpy(pret->data,pdata,len);
	}
	return pret;
}

typedef void* (*pthrd_fun)(void*);

void * thrd_function_1(void *parg)
{
	int iexit;
	PJOB pjob;
	int count = 0;
	cout << "thrd id is:  " << pthread_self() << " run..." << endl;
	while(!flag_exit)
	{
		pjob = packjob(count++,(byte*)data,strlen(data));
		//锁定互斥体
		pthread_mutex_lock(&mutex);

		g_thrd_queue.push(pjob);

		//信号量值+1
		sem_post(&sem_job_count);
		
		//解除互斥体
		pthread_mutex_unlock(&mutex);
		
	}

	cout << "thrd id is:  " << pthread_self() << " exit!" << endl;
	iexit = 0;
	pthread_exit(&iexit);
}

void * thrd_function_2(void *parg)
{
	int iexit;
	PJOB pjob;
	cout << "thrd id is:  " << pthread_self() << " run..." << endl;
	while(!flag_exit)
	{
		//等待信号量+1
		sem_wait(&sem_job_count);
		
		//锁定互斥体
		pthread_mutex_lock(&mutex);

		pjob = g_thrd_queue.front();
		g_thrd_queue.pop();
		//解除互斥体
		pthread_mutex_unlock(&mutex);

		cout << "id :"<<pjob->id << endl;
		cout <<"len :"<< pjob->len << endl;
		cout <<"data :" << (char*) pjob->data << endl;

		//释放内存
		free(pjob);
	}

	cout << "thrd id is:  " << pthread_self() << " exit!" << endl;
	iexit = 0;
	pthread_exit(&iexit);
}

int main(int argc,char *argv[])
{
	pthread_t thread_id1;
	pthread_t thread_id2;
	int iret;
	
	cout << "pid id is:  " << getpid() << endl;

	//安置信号处理函数
	signal(SIGUSR1,handlesignal);

	//初始化信号量
	sem_init(&sem_job_count,0,0);
	
	iret = pthread_create(&thread_id1,NULL,thrd_function_1,NULL);

	if(iret != 0)
	{
		iret = 1;
	}

	iret = pthread_create(&thread_id2,NULL,thrd_function_2,NULL);
	if(iret != 0)
	{
		iret = 1;
	}

	//等待子线程的退出
	pthread_join(thread_id1,NULL);
	pthread_join(thread_id2,NULL);

	//释放内存
	while(!g_thrd_queue.empty())
	{
		PJOB pjob;
		pjob = g_thrd_queue.front();
		g_thrd_queue.pop();

		free(pjob);
	}
	cout << "main thread is exit!" << endl;
	return iret;
}

注意:sem_trywait和pthread_mutex_trylock用法类似。

3、  条件变量

用的api函数有:pthread_cond_init、用pthread_cond_signal、pthread_cond_wait、,pthread_cond_broadcast、pthread_cond_destroy

示例:

//thread_con.cc

#include<iostream>
#include<queue>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<signal.h>
#include<semaphore.h>

using namespace std;

typedef unsigned int u32;
typedef unsigned char byte;
bool flag_exit = false;
char *data ="test pthread mutex!";


typedef struct job
{
	u32 id;
	u32 len;
	byte data[1];
}JOB,*PJOB;

queue<PJOB> g_thrd_queue;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t g_thread_flag_cv;

typedef void (*sighandler_t)(int);

void handlesignal(int signal)
{
	cout << "+++handlesignal+++" << endl;
	flag_exit = true;
}

PJOB packjob(u32 id,byte *pdata,u32 len )
{
	PJOB pret = NULL;
	int size = sizeof(JOB) + len;
	pret = (PJOB)malloc(size);
	if(pret != NULL)
	{
		memset(pret,0,size);
		pret->id = id;
		pret->len = size;
		memcpy(pret->data,pdata,len);
	}
	return pret;
}

typedef void* (*pthrd_fun)(void*);

void * thrd_function_1(void *parg)
{
	int iexit;
	PJOB pjob;
	int count = 0;
	cout << "thrd id is:  " << pthread_self() << " run..." << endl;
	
	//锁定互斥体
	pthread_mutex_lock(&mutex);
		
	while(count <10)
	{
		pjob = packjob(count++,(byte*)data,strlen(data));

		g_thrd_queue.push(pjob);
	}
	
	flag_exit = true;
	
	//触发条件变量
	pthread_cond_signal(&g_thread_flag_cv);
	
	//解除互斥体
		pthread_mutex_unlock(&mutex);

	cout << "thrd id is:  " << pthread_self() << " exit!" << endl;
	iexit = 0;
	pthread_exit(&iexit);
}

void * thrd_function_2(void *parg)
{
	int iexit;
	PJOB pjob;
	cout << "thrd id is:  " << pthread_self() << " run..." << endl;
	
	//锁定互斥体
	pthread_mutex_lock(&mutex);
	
	//等待条件变量
	while(!flag_exit)
		pthread_cond_wait(&g_thread_flag_cv,&mutex);
		
	while(!g_thrd_queue.empty())
	{

		pjob = g_thrd_queue.front();
		g_thrd_queue.pop();
		

		cout << "id :"<<pjob->id << endl;
		cout <<"len :"<< pjob->len << endl;
		cout <<"data :" << (char*) pjob->data << endl;

		//释放内存
		free(pjob);
	}

  //解除互斥体
  pthread_mutex_unlock(&mutex);
		
	cout << "thrd id is:  " << pthread_self() << " exit!" << endl;
	iexit = 0;
	pthread_exit(&iexit);
}

int main(int argc,char *argv[])
{
	pthread_t thread_id1;
	pthread_t thread_id2;
	int iret;
	
	cout << "pid id is:  " << getpid() << endl;

	//安置信号处理函数
	signal(SIGUSR1,handlesignal);

	//初始化条件量
	pthread_cond_init(&g_thread_flag_cv,NULL);
	
	iret = pthread_create(&thread_id1,NULL,thrd_function_1,NULL);

	if(iret != 0)
	{
		iret = 1;
	}

	iret = pthread_create(&thread_id2,NULL,thrd_function_2,NULL);
	if(iret != 0)
	{
		iret = 1;
	}

	//等待子线程的退出
	pthread_join(thread_id1,NULL);
	pthread_join(thread_id2,NULL);

	//释放内存
	while(!g_thrd_queue.empty())
	{
		PJOB pjob;
		pjob = g_thrd_queue.front();
		g_thrd_queue.pop();

		free(pjob);
	}
	
	pthread_cond_destroy(&g_thread_flag_cv);
	
	cout << "main thread is exit!" << endl;
	return iret;
}

注意:pthread_cond_broadcast 函数会将所有等待该条件变量的线程解锁而不是

仅仅解锁一个线程。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值