Linux 多线程 pthread库初探
Linux 多线程 pthread库用法(一)Linux 多线程编程基介绍Linux 线程有时候也叫 Light Weight Process LWP 轻量级线程,是进程的一个执行流,有自己的执行栈,是操作系统调度的最小单位。 多线程优势在于切换开销小,同进程内通信方便,涉及IO等阻塞性操作时可以单独开一个线程不阻塞主流程,不足之处健壮性不如多进程,一个线程crash,那么所在进程就都...
Linux 多线程 pthread库用法(一)
Linux 多线程编程基介绍
Linux 线程有时候也叫 Light Weight Process
LWP 轻量级线程,是进程的一个执行流,有自己的执行栈,是操作系统调度的最小单位。 多线程优势在于切换开销小,同进程内通信方便,涉及IO等阻塞性操作
时可以单独开一个线程不阻塞主流程,不足之处健壮性不如多进程,一个线程crash,那么所在进程就都crash了。这两篇入门的文章写的不错:
本文主要总结下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 tracedW
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 leaderl
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;
void *ret1, *ret2;
pthread_create(&tid1, NULL, thread1_main, NULL);
pthread_create(&tid2, NULL, thread2_main, NULL);
while (1) {
printf("This is thread main\n");
sleep(1);
}
pthread_join(tid1, &ret1);
pthread_join(tid2, &ret2);
return 0;
}
一个简单的makefile
# 编译当前目录所有的 .c 文件,注意链接 -lpthread
# 开启所有 warning,按照错误处理
TARGETS = mytest.bin
CFLAGS = -Wall -Werror -m64 -g3 -std=c99
$(TARGETS) : $(wildcard *.c)
$(CC) $(CFLAGS) $^ -o $@ -lpthread
.PHONY : clean
clean:
rm *.bin
更多推荐
所有评论(0)