Linux多线程编程与线程间通信机制

本文介绍了Linux环境下多线程编程的重要性,包括如何创建线程、进行线程同步(重点讨论互斥锁)以及线程间通信(重点讲解消息队列)。线程创建涉及`pthread_create`、`pthread_detach`和`pthread_cancel`函数,线程同步通过互斥锁实现,线程通信使用消息队列,如`msgget`、`msgsnd`和`msgrcv`函数。

   Linux中多线程编程技术被广泛使用,这主要是因为多线程可以提升程序的运行效率和便利性。在现在的比较大一点的linux程序中,没有使用多线程编程技术是不可想象的。有多线程,那么就涉及到线程间的通信问题,简单来说就是线程A怎么把消息传递给线程B。目前线程间通信的用的比较多的主要技术有消息队列、共享内存。本文就来讲讲linux中多线程编程的实现,以及利用消息队列进行线程间通信。

 

、线程的创建

线程的创建首先需要包含头文件:

#include <pthread.h>

1创建线程的函数:

pthread_create(pthread_t ptid,NULL,(void *)cmd,NULL);

返回值为0时表示线程创建成功。

2将该子线程的状态设置为detached,以便该线程运行结束后自动释放其占用的资源

pthread_detach(pthread_t *ptid);

3kill一个线程

pthread_cancel(pthread_t tid);

线程之间的同步

    多线程编程时经常会出现多个线程同时去操作同一个资源的情况,比如说线程A和线程B在某一个时间内都想去操作同一个全局变量C,那么这个时候就需要进行线程同步。线程A告诉线程B,我正在对全局变量C进行操作,等我操作完成后,你们再来吧。目前线程同步的技术主要有互斥锁(mutex)和信号量(Semaphore)。本文主要讲一下互斥锁。

1 定义一个互斥锁

pthread_mutex_t mutex;

2 互斥锁上锁

pthread_mutex_lock(mutex);

3 解锁

pthread_mutex_unlock(mutex);

线程间通信

    线程之间有时候需要传递消息,比如说线程A负责处理网络数据,当网络有数据到来时,线程A就开始工作了,它把处理的结果反馈给主线程。告诉主线程有网络事件到来,而且有数据需要你处理。线程间通信用的比较多的就是消息队列和共享内存。本文主要讲一下消息队列的使用。

1 消息的创建

unsigned int threadType

key_t key = 1050 + threadType;

msgget(key, IPC_CREAT|0666));

2 发送消息

msgsnd(unsigned int msgid, void * msg, unsigned int msgsize,IPC_NOWAIT)

3 接收消息

msgrcv(msgid, &msg, sizeof(msg)-sizeof(long), 0,MSG_NOERROR);

 

、编程实例

   本文将创建实例来讲解

typedef struct mesageThread
{
	pthread_t			tid;
	unsigned int		thread_type;	
	void				*pre;
	void			 	*next;
}_mesageThread,*_pmesageThread;

typedef struct thread_head
{
	pthread_mutex_t		mutex;		
	pthread_t			current;	
	unsigned int		sum;	
	_pmesageThread	list;
}_thread_head,*_pthread_head;


_thread_head	threadhead;

int createThread(pthread_t *ptid,void (* cmd)(),unsigned int thread_type)
{
	int ret,result = -1;
	ret = pthread_create(ptid,NULL,(void *)cmd,NULL); 
	if(ret == 0)
	{
		pthread_detach(*ptid);  
								
		create_msg(thread_type);

		addto_list(ptid,thread_type);	// 线程添加到队列中
		result = 1;
	}
	return result;
}

int addto_list(pthread_t *ptid,unsigned int thread_type)
{
	int result = -1;
	_mesageThread pthreadnow = NULL;
	_mesageThread pthreadnode = (_mesageThread)malloc(sizeof(_mesageThread));
	if(pthreadnode != NULL)
	{
		pthreadnode->pre 			= NULL;
		pthreadnode->next 			= NULL;

		pthreadnode->thread_type 	= thread_type;
		pthreadnode->tid 			= *ptid;

		pthread_mutex_lock(&threadhead.mutex);
		if(threadhead.list == NULL)				
		{
			threadhead.current = 0;
			threadhead.sum = 1;
			threadhead.list = pthreadnode;			
			pthread_mutex_unlock(&threadhead.mutex);
		}
		else
		{
			pthread_mutex_unlock(&threadhead.mutex);
			if(getListEnd(&pthreadnow) > 0)			
			{
				pthread_mutex_lock(&threadhead.mutex);
				pthreadnode->pre = pthreadnow;		
				pthreadnow->next = pthreadnode;	
				threadhead.sum++;
				pthread_mutex_unlock(&threadhead.mutex);
			}
		}
		result = 1;
	}
	return result;
}


int getListEnd(_mesageThread *end)
{
	int result = -1;
	pthread_mutex_lock(&threadhead.mutex);
	_mesageThread p = threadhead.list;
	*end = p;

	if(threadhead.list != NULL)
	{
		while(1)
		{
			if(p->next == NULL)
			{
				*end = p;
				result = 1;
				break;
			}
			else p = p->next;
		}
	}
	
	pthread_mutex_unlock(&threadhead.mutex);
	return result;
}

typedef struct msgInfo
{
	unsigned int type;		
	unsigned int msgid;			
	void		 *pre;
	void		 *next;
}_msgInfo,*_pmsgInfo;

typedef struct msglist
{
	pthread_mutex_t mutex;
	_pmsgInfo list;

}_msghead,*_pmsghead;

_msglist_head	msgHead;


enum
{
     THREADMAIN = 1,
     THREAD_A,
};

 通过线程类型得到消息类型

int getMessageId(unsigned int type,unsigned int *msgid)
{
	int result = -1;

	pthread_mutex_lock(&msgHead.mutex);
	_pmsglist_info pmsglistnow = msgHead.list;
	while(1)
	{
		if(pmsglistnow == NULL)break;
		if(pmsglistnow->thread_type == type)
		{
			*msgid = pmsglistnow->msgid;
			result = 1;
			break;
		}
		pmsglistnow = pmsglistnow->next;
	}
	pthread_mutex_unlock(&msgHead.mutex);

	return result;
}

void sendMessage(unsigned char type,void *msg)
{
    unsigned int msgid;
	unsigned int msgsize = 0;
    if(get_msgid(type,&msgid)> 0)
    {
        msgsnd(msgid, msg, msgsize, IPC_NOWAIT);
    }
}

typedef struct threadA_msg
{
     //需要处理的消息
};

typedef struct threadMain_msg
{
     //需要处理的消息
};

创建线程A

void ThreadA()
{
    threadA_msg msg;
	unsigned int msgid;
    if(get_msgid(THREAD_A,&msgid) < 0) continue;
	if(msgrcv(msgid, &msg, sizeof(thread_msg)-sizeof(long), 0, MSG_NOERROR)<0)
	{
		printf("thread A message recive error\n ");
		continue;
	}
	if()//需要触发的发送消息的条件
	{
	     sendMessage(THREADMAIN,&msg);
	}
}

创建主线程

void main()
{
    pthread_t id;
	int ret;
	unsigned int msgid;
	threadMain_msg msg;
    createThread(THREADMAIN);
	createThread(id,ThreadA,THREAD_A);
	while(1)
	{
	    if(get_msgid(THREADMAIN,&msgid) < 0) continue;
	    ret = msgrcv(msgid, &msg, sizeof(_mthread_msg)-sizeof(long), 0, MSG_NOERROR);
	    if( ret < 0)
	    {
		    printf("main Thread msg rec error\n ");
		    continue;
	    }
	}
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值