异步:异步和同步是相对的,同步就是顺序执行,执行完一个再执行下一个,需要等待、协调运行。异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。线程就是实现异步的一个方式。异步是让调用方法的主线程不需要同步等待另一线程的完成,从而可以让主线程干其它的事情。
getpid()
得到的是进程的pid,在内核中,每个线程都有自己的PID,要得到线程的PID,必须用syscall(SYS_gettid)
;pthread_self
函数获取的是线程标识符ID,线程ID在某进程中是唯一的,在不同的进程中创建的线程可能出现ID值相同的情况。是该线程在共享区中开辟空间的对应首地址其作用对应进程中 getpid() 函数。
pthread_t pthread_self(void);
pthread_t:typedef unsigned long int pthread_t;
返回值:成功:0; 失败:无!
线程ID:pthread_t类型,本质:在Linux下为无符号整数(%lu),其他系统中可能是结构体实现
线程ID是进程内部,识别标志。(两个进程间,线程ID允许相同)
其作用,对应进程中fork() 函数。( 链接这些线程函数库时要使用编译器命令的“-lpthread”选项)
`int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);`
#include
#include
#include
#include
#include
void* func(void* arg)
{
while(1)
{
printf("i am work thread\n");
sleep(1);
}
return NULL;
}
int main()
{
pthread_t tid;
int ret = pthread_create(&tid, NULL, TStart, NULL);
if(ret < 0)
{
perror("wrong!");
return -1;
}
while(1)
{
printf("i am main thread\n");
sleep(1);
}
return 0;
}
主进程结束后,所有的工作线程都会结束。该进程的进程pid=3472
pstack 3472
查看该进程的堆栈信息:
线程默认共享数据段、代码段等地址空间,常用的是全局变量。而进程不共享全局变量,只能借助mmap
1 #include <stdio.h>
2 #include <signal.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <sys/wait.h>
6 #include <pthread.h>
7 int var=100;
8 void* TStart(void* arg)
9 {
10 var = 200;
11 printf("thread\n");
12 return NULL;
13 }
14
15 int main()
16 {
17 printf("At first var = %d\n", var);
18
19 pthread_t tid;
20 pthread_create(&tid, NULL, TStart, NULL);
21 sleep(1);
22
23 printf("after pthread_create, var = %d\n", var);
24
25 return 0;
26 }
void pthread_exit(void *retval);
参数:返回信息,返回给等待线程退出的执行流信息,可传递NULL,谁调用谁退出int pthread_cance1 (pthread_t thread);
thread:线程标识符,调用该函数的执行流可以取消其他线程,但是需要知道其他线程的线程标识符也可以执行流自己取消自己,传入自己的线程标识符int pthread_cancel(pthread_t thread);
thread:线程标识符,调用该函数的执行流可以取消其他线程注意:
1.线程在创建出来的时候,属性当中默认是joinable属性(意味着线程在退出的时候需要其他执行流来回收线程的资源)
2.使用exit将指定线程退出,可以吗? 结论:线程中,禁止使用exit函数,会导致进程内所有线程全部退出。
获取线程退出状态 其作用,对应进程中 waitpid() 函数
int pthread_join(pthread_t thread, void **retval);
#include
#include
#include
#define THREADCOUNT 1
void* myStartThread(void* arg)
{
(void)arg;
while(1)
{
sleep(5);
printf("i am workthread\n");
pthread_exit(NULL);
}
}
int main()
{
pthread_t tid[THREADCOUNT];
for(int i = 0; i < THREADCOUNT; i++)
{
int ret = pthread_create(&tid[i], NULL, myStartThread, NULL);
if(ret < 0)
{
perror("pthread_create");
return -1;
}
}
for(int i = 0; i < THREADCOUNT; i++)
{
pthread_join(tid[i], NULL);
}
while(1)
{
printf("i am main thread\n");
sleep(1);
}
return 0;
}
int pthread_detach(pthread_t thread);
改变线程的属性,将joinable属性改变成为detach属性,当线程退出的时候,不需要其他线程在来回收退出线程的资源,操作系统会默认回收掉
#include
#include
#include
#define THREADCOUNT 1
void* myStartThread(void* arg)
{
//1.pthread_detach(pthread_self());
(void)arg;
while(1)
{
sleep(5);
printf("i am workthread\n");
}
}
int main()
{
pthread_t tid[THREADCOUNT];
for(int i = 0; i < 1; i++)
{
int ret = pthread_create(&tid[i], NULL, myStartThread, NULL);
if(ret < 0)
{
perror("pthread_create");
return -1;
}
}
for(int i = 0; i < THREADCOUNT; i++)
{
//2.pthread_detach(tid[i]);
}
while(1)
{
printf("i am main thread\n");
sleep(1);
}
return 0;
}
可以放在工作线程之中,刚进入工作线程就进行分离,也可以在主线程中根据工作线程ID进程分离。