1.线程存在于进程中,当运行一个程序的时候,linux创建一个新进程,这个新进程中创建了一个主线程,该主线程又能创建其他的线程
2.创建一个新进程的时候,子进程在父进程中初始化运行,父进程的虚拟内存和文件描述符等复制给了子进程,子进程能够修改内存,关闭文件描述符并且不影响父进程,同样的,父进程中的这些操作也不会影响到子进程.
3,当创建一个新线程的时候,不存在任何的拷贝现象,正在创建和已经创建的线程共享内存空间,文件描述符等系统资源,当其中一个线程修改了内存或者关闭了文件描述符,立马就能影响到其他的线程运行.由于一个进程和该进程中的所有线程同一时间只能执行同一个程序,因此只要某个线程执行了exec函数,所有的线程就都停止了.
4.linux中和线程相关的在头文件<pthread.h>中,在链接时要加上libpthread.so,也即加上-lpthread选项.进程中的线程用线程id来区分(pthread_t类型的变量),每个线程一创建就会开始执行线程函数,该函数退出了线程也随之退出,
5.用pthread_create创建了一个新线程后,原线程继续执行,同时新建线程也开始执行线程函数.pthread_create函数有四个参数,第一个是pthread_t变量指针,指针指向新创建的线程id,一个线程属性对象的指针,指向线程函数的函数指针,以及线程函数中的形参指针(void *类型)
#include<stdio.h> #include<pthread.h> #include<stdlib.h> #include<unistd.h> void *printx(void *unused) { int i = 0; while(i < 10) { fprintf(stderr,"x\n"); i++; } return NULL;//或者pthread_exit(NULL);也可以退出该线程 } int main() { pthread_t thread_id; pthread_create(&thread_id,NULL,printx,NULL); while(1) { fprintf(stderr,"o\n"); sleep(2); } return 0; }
此时存在一种情况就是如果主线程以及结束了但分线程还未结束,程序就会等不到分线程的执行结果就会退出.分线程的退出有两种情况,一种的在线程函数中return,另一个就是在线程函数中显示的调用pthread_exit()函数,pthread_exit函数的参数为线程函数要return的类型.
6.pthread_create的第四个参数是传递给线程函数的形参,一般用一个struct变量将要传递的参数值储存起来,下面给出创建两个线程,每个线程执行相同的函数,但传递给线程函数的参数不同#include<stdio.h#include<pthread.h#include<unistd.h>
struct params { char character; int count; }; void *print_params(void *parameters) { struct params * p = (struct params *)parameters; for(int i = 0;i < p->count;i++) { printf("%c\n",p->character); fflush(stdout); } return NULL; } int main() { pthread_t thread_id1,thread_id2; struct params p1,p2; p1.character = ‘x‘; p1.count = 10; p2.character = ‘o‘; p2.count = 5; pthread_create(&thread_id1,NULL,print_params,&p1); pthread_create(&thread_id2,NULL,print_params,&p2); pthread_join(thread_id1,NULL);
pthread_join(thread_id2,NULL);
}
此时存在一个问题就是作为主线程内的局部变量p1,p2,两个分线程里有指针指向这两个变量,主线程结束后p1,p2释放了,但分线程仍然去获取这两个变量的值,因此就会发生错误,解决办法就是用pthread_join函数去等待分线程执行的结束,类似于进程中的wait函数功能,pthread_join函数的第一个参数是要等待的线程id,第二个参数是指向该线程的返回值的指针(void *),若不care线程返回值,可以用NULL代替.若想得到线程的返回值,可以通过如下方式获得:
#include<stdio.h> #include<pthread.h> #include<unistd.h> #include<stdlib.h> struct params { char character; int count; }; void* print_params(void *parameters) { struct params * p = (struct params *)parameters; for(int i = 0;i < p->count;i++) { printf("%c\n",p->character); fflush(stdout); } int temp = 3; return (void *)temp; } int main() { pthread_t thread_id1,thread_id2; struct params p1,p2; p1.character = ‘x‘; p1.count = 10; p2.character = ‘o‘; p2.count = 5; pthread_create(&thread_id1,NULL,print_params,&p1); pthread_create(&thread_id2,NULL,print_params,&p2); int res; pthread_join(thread_id1,(void **) &res); printf("res=%d\n",res); pthread_join(thread_id2,NULL); return 0; }
输出为:
x x x x x x x x x x o o o o o res=3
7.为了防止在自己线程内pthread_join自己这个线程的id,在join之前可以通过pthread_equal判断是否在自己线程内:
if(!pthread_equal(pthread_self(),otherThreadId)) pthread_join(otherThreadId,NULL);
8.前面说到pthread_create函数的第二个参数是要创建的线程属性,如果用默认值的话该位置的值为NULL,若要用到特定的一些线程属性,需要遵循以下步骤来生成带特定线程属性的线程:
1).