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

1994

被折叠的 条评论
为什么被折叠?



