`
oolala
  • 浏览: 99828 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
09c341db-7f05-3f2b-a572-9ee69a5d8a77
unix环境高级编程
浏览量:21688
社区版块
存档分类
最新评论

Unix环境高级编程笔记:11、线程

阅读更多
1、线程概念
    线程包含了表示进程内执行环境必须的信息,其中包括进程中标识线程的线程ID、一组寄存器值、栈、调度优先级和策略、信号屏蔽字、errno变量以及线程私有数据。进程的所有信息对该进程的所有线程都是共享的,包括可执行的程序文本、程序的全局内存和堆内存、栈以及文件描述符。
 
 

 
 
2、线程标识
    线程ID用pthread_t数据类型表示
    
必须使用函数对二个线程ID进行比较
       #include <pthread.h>
       int pthread_equal(pthread_t t1, pthread_t t2);
 
通过pthread_self获得自身线程ID
#include <pthread.h>
pthread_t pthread_self(void);
 
 

 
 
3、创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

当pthread_create成功返回时,由tidp指各的内存单元被设置为新创建线程的线程ID

attr参数用于定制各种不同的线程属性。
 
pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a,所以在使用pthread_create()创建线程,以及调用 pthread_atfork()函数建立fork处理程序时,需要链接该库。
在编译中要加 -lpthread参数
gcc thread.c -o thread -lpthread

create_thread.c
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
 
pthread_t ntid;
 
void printids(const char *s) {
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
printf("%s pid %u tid %u (0x%x)\n",s,(unsigned int)pid,(unsigned int)tid,(unsigned int)tid);
}
 
void * thr_fn(void * arg) {
printids("new thread:");
return((void *)0);
}
 
int main(int argc, char **argv) {
int err;
err = pthread_create(&ntid,NULL,thr_fn,NULL);
if(err != 0) {
printf("pthread create error");
}
printids("main thread:");
sleep(1);
exit(0);
}
 
 
 
 

 
4、线程终止
    如果进程中的任一线程调用了exit、_Exit或者_exit,那么整个进程就会终止。
    如果信号的默认动作是终止进程,那么把信号发送到线程会终止整个进程。
 
    线程退出方式
    1)线程只是从启动例程中返回,返回值是线程的退出码
    2)线程可以被同一进程中的其他线程取消。
    3)线程调用pthread_exit
    
       #include <pthread.h>
       void pthread_exit(void *retval);
 
retval是一个无类型指针,与传给启动例程的单个参数类似。进程中的其他线程可以通过调用pthread_join访问到这个指针。
   #include <pthread.h>
   int pthread_join(pthread_t thread, void **retval);
调用线程将一直被阻塞,直到指定的线程调用pthread_exit,从启动例程中返回或者被取消。
 
获取已终止的线程的退出码
thread_exit_code.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
 
void *thr_fn1(void *arg) {
printf("thread 1 returning\n");
return ((void*)1);
}
 
void *thr_fn2(void *arg) {
printf("thread 2 returning\n");
return ((void*)2);
}
 
int main(int argc, char **argv) {
int err;
pthread_t tid1,tid2;
void *tret;
 
err = pthread_create(&tid1,NULL,thr_fn1,NULL);
if(err != 0) {
printf("can`t create thread1 %s",strerror(err));
exit(0);
}
err = pthread_create(&tid2,NULL,thr_fn2,NULL);
if(err != 0) {
printf("can`t create thread1 %s",strerror(err));
exit(0);
}
 
 
err = pthread_join(tid1,&tret);
if(err != 0) {
printf("can`t join with thread 1 %s",strerror(err));
exit(0);
}
printf("thread 1 exit code %s\n",strerror(err));
 
 
err = pthread_join(tid2,&tret);
if(err != 0) {
printf("can`t join with thread 2 %s\n",strerror(err));
exit(0);
}
printf("thread 2 exit code %s\n",strerror(err));
exit(0);
}
 
 
 
 
线程可以通过调用pthread_cancel函数来请求取消同一进程中的其他线程。
       #include <pthread.h>
 
       int pthread_cancel(pthread_t thread);
 
 
 

 
5、线程同步
    互斥变量用pthread_mutex_t数据类型表示,在使用互斥变量以前,必须首先对它进行初始化。
    可以把它设置为常量PTHREAD_MUTEX_INITALIZER(只对静态分配的互斥量)
    通过调用pthread_mutex_init函数进行初始化。
    如果动态的分配互斥量(malloc),那么释放内存前需要调用pthread_mutex_destroy
       #include <pthread.h>
 
       int pthread_mutex_destroy(pthread_mutex_t *mutex);
       int pthread_mutex_init(pthread_mutex_t *restrict mutex,
              const pthread_mutexattr_t *restrict attr);
       pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
 
对互斥量进行加锁,需要调用pthread_mutex_lock,如果互斥量已经上锁,调用线程将阻塞直到互斥量被解锁。对互斥量解锁,需要调用
pthread_mutex_unlock
       #include <pthread.h>
 
       int pthread_mutex_lock(pthread_mutex_t *mutex);
       int pthread_mutex_trylock(pthread_mutex_t *mutex);
       int pthread_mutex_unlock(pthread_mutex_t *mutex);
如果不希望被阻塞,它可以使用pthread_mutex_trylock尝试对互斥量进行加锁。
如果调用pthread_mutex_trylock时互斥量处于未锁住状态,那么将锁住互斥量,不会出现阻塞并返回0,否则失败
 
 
分享到:
评论

相关推荐

    UNIX环境高级编程881

    Unix环境高级编程笔记I/O文件系统进程线程进程间通信一.文件I/O三.标准I/O库八.高级I/O二.文件和目录四.进程环境五.进程控制六.线程七.线程控制九

    学习笔记多线程Unix编程

    学习笔记多线程Unix编程

    Linux系统设计-Linux系统编程笔记

    Linux系统是一个免费使用和自由传播的类Unix操作系统,基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统,Linux是许多企业...

    leetcode伪代码-Diary:日记

    leetcode伪代码 学习日记 2021.03.09 : 某司waf功能分析,寻找攻击面 复习之前做过的虚拟化相关ctf题,以及几道...环境高级编程多线程部分的学习,做了几道和多线程有关的题,对于多线程初窥门径 尝试用rust出一道逆向

    Linux系统设计-linux 编程环境学习笔记,含 linux 基本命令,linux 操作系统,linux 下 C++ 编程等

    Linux系统是一个免费使用和自由传播的类Unix操作系统,基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统,Linux是许多企业...

    c#学习笔记.txt

    C#学习笔记(2)【大 中 小】【打印】【加入收藏】【关闭】 【收藏到新浪ViVi】【收藏到365KEY】 浏览字号:日期:2004-07-11 人气:8092 出处: write by cash(天下第七) 2002.01.20 版权所有,翻录不究 cashcao@...

    Linux系统设计-Linux系统编程学习笔记

    Linux系统是一个免费使用和自由传播的类Unix操作系统,基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统,Linux是许多企业...

    linux学习笔记(包含Linux系统和shell编程).zip

    Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix...

    Linux系统设计-linux系统网络编程学习笔记

    Linux系统是一个免费使用和自由传播的类Unix操作系统,基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统,Linux是许多企业...

    Linux系统设计-Linux系统及shell编程 整理笔记

    Linux系统是一个免费使用和自由传播的类Unix操作系统,基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统,Linux是许多企业...

    Java/JavaEE 学习笔记

    Unix 学习笔记..........7 一、Unix前言............7 二、Unix基础知识....7 三、Unix常用命令....8 四、 文件系统权限.21 五、软硬连接的区别..........................22 六、范例程序...........22 七、网络...

    UnixProgramming

    这是我学习Unix(主要是linux)系统编程与网络编程的笔记,附上部分源码 系统编程 进程 创建fork 执行exec 销毁wait/waitpid(SIGCHLD) 进程间通信: 匿名管道pipe,命名管道(FIFO)mkfifo System V IPC(还有一组POSIX...

    J2EE学习笔记(J2ee初学者必备手册)

    Unix 学习笔记7 一、Unix前言............7 二、Unix基础知识....7 三、Unix常用命令....8 四、 文件系统权限.21 五、软硬连接的区别..........................22 六、范例程序...........22 七、网络基本命令...26...

    我的APUE2读书笔记

    以原书的1-16章为主,包括基本概念、POSIX诸标准、文件、信号、线程、进程间通信等。 参考了一些其它资料结合个人分析,对书中的知识点、重点、难点疑点进行了部分补充。 原连载于 ...

    C-plus-plus-Series:学习C ++的旅程

    UNIX编程 C ++多线程 C ++入门笔记与归纳 C ++入门手册第五版笔记与知识点整合 一.C ++基础知识 二。函数 三。类 四.IO库 ##五。顺序容器 六。泛型编程 七。关联容器 八。动态内存 九。拷贝控制 十。重载运算与类型...

Global site tag (gtag.js) - Google Analytics