您的位置:首页 > 运维架构 > Linux

Linux 多线程 pthread库用法(一)

2016-04-19 23:54 393 查看
Linux 多线程 pthread库用法(一)

Linux 多线程编程基介绍

Linux 线程有时候也叫
Light Weight Process
LWP 轻量级线程,是进程的一个执行流,有自己的执行栈,是操作系统调度的最小单位。 多线程优势在于切换开销小,同进程内通信方便,涉及
IO等阻塞性操作
时可以单独开一个线程不阻塞主流程,不足之处健壮性不如多进程,一个线程crash,那么所在进程就都crash了。这两篇入门的文章写的不错:

- Linux多线程编程

- pthreads 的基本用法

本文主要总结下Linux多线程库 pthread 的最基本用法,进一步使用后面文字再介绍。

创建线程的函数接口 phtread_create

创建线程的 Linux 库函数,在 /usr/include 目录下, 声明如下:

/* Create a new thread, starting with execution of START-ROUTINE
getting passed ARG.  Creation attributed come from ATTR.  The new
handle is stored in *NEWTHREAD.  */
extern int pthread_create (pthread_t *__restrict __newthread,
const pthread_attr_t *__restrict __attr,
void *(*__start_routine) (void *),
void *__restrict __arg) __THROWNL __nonnull ((1, 3));
// (gdb) pt pthread_t
// type = unsigned long ,也可以在库函数中看到其定义,ptype 层层展开声明,最终都能到基本数据类型
// mac os 中 pthread 是一个结构体

// 定义在 pthreadtypes.h 中
/* Thread identifiers.  The structure of the attribute type is not
exposed on purpose.  */
typedef unsigned long int pthread_t;

union pthread_attr_t
{
char __size[__SIZEOF_PTHREAD_ATTR_T];
long int __align;
};
// pthread_attr_t 在对该结构进行处理之前必须进行初始化,在使用后需要对其去除初始化

#ifdef __x86_64__
# if __WORDSIZE == 64
#  define __SIZEOF_PTHREAD_ATTR_T 56


函数声明中用到了 restrict 关键字,详细理解此关键字看这里C语言关键字restrict。由 restrict 修饰的指针是最初唯一对指针所指向的对象进行存取的方法,仅当第二个指针基于第一个时,才能对对象进行存取。由 restrict 修饰的指针主要用于函数形参,或指向由 malloc() 分配的内存空间。restrict 数据类型不改变程序的语义。 编译器能通过作出 restrict 修饰的指针是存取对象的唯一方法的假设,更好地优化某些类型的例程。

Linux -> man-pages

第一个参数为指向线程标识符的指针。

第二个参数用来设置线程属性. 具体介绍可以看:Posix多线程编程—线程属性

第三个参数是线程运行函数的起始地址。

第四个参数是运行函数的参数。

一个 pthread 的最基础使用例子

跑起来一个Linux多线程程序,可以用
ps ufx|grep XXX (XXX 程序的名字)
查看进程的状态,
l
就是多线程状态的意思,还可以看进程启动时间,运行的cpu时间。
man ps
有详细解释:

D
uninterruptible sleep (usually IO)

R
running or runnable (on run queue)

S
interruptible sleep (waiting for an event to complete)

T
stopped, either by a job control signal or because it is being traced

W
paging (not valid since the 2.6.xx kernel)

X
dead (should never be seen)

Z
defunct (“zombie”) process, terminated but not reaped by its parent

BSD formats
, Linux 下执行都会有:

<
high-priority (not nice to other users)

N
low-priority (nice to other users)

L
has pages locked into memory (for real-time and custom IO)

s
is a session leader

l
is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)

+
is in the foreground process group

下面是一个最基本的例子:

/* 举例三个线程: 主线程 + create 两个 */
/* 可以直接在 xcode 中执行,如果在linux 上跑编译的时候用下面的makefile, 主要是需要 -lpthread */
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void* thread1_main(void *p)
{
while(1) {
printf("This is thread 1\n");
sleep(1);
}
return NULL;
}

void* thread2_main(void *p)
{
while(1) {
printf("This is thread 2\n");
sleep(1);
}
return NULL;
}

int main()
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, thread1_main, NULL);
pthread_create(&tid2, NULL, thread2_main, NULL);
while(1){
printf("This is thread main\n");
sleep(1);
}
return 0;
}


一个简单的
makefile


# 编译当前目录所有的 .c 文件,注意链接 -lpthread
# 变量赋值空格不敏感,缩进必须用TAB,规则部分如果换行要加 \ ,类似宏
# 开启所有 warning,按照错误处理
TARGETS = mytest.bin
CFLAGS  = -Wall -Werror -m64 -g3 -std=c99

$(TARGETS) : $(wildcard *.c)
$(CC) $(CFLAGS) $^ -o $@ -lpthread

.PHONY : clean
clean:
rm *.bin


下一篇着重介绍下Linux 多线程的同步与互斥。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: