进程是资源管理的最小单元,线程是程序执行的最小单元。在操作系统的设计上,从进程演化出线程,最主要的目的就是更好的支持SMP以及减小(进程/线程)上下文切换开销。
就像进程有一个PID一样,每个线程也有自己的线程ID,但线程ID只在它所属的环境中有效;
创建一个新的线程可以通过调用pthread_create()函数来创建;
函数原型为:
#include <pthread.h>
int pthread_create(pthread_t *thread_addr_t, *addr, void *(*start_rtn) (void), void *restrict arg;
第一个参数是一个指针,它指向一个pthread_t类型的结构,再创建一个线程时,这个指针指向的变量里会写入
新线程的ID,第二个参数对线程的属性进行设置;一般默认为NULL;
最后两个参数分别是线程将要启动执行的函数以及将要传递给这个函数的参数。
下面的代码是创建一个新的线程:
1 #include <stdio.h> 2 #include <string.h> 3 #include <unistd.h> 4 #include <fcntl.h> 5 #include <pthread.h> 6 #include <stdlib.h> 7 8 /*新线程要执行的函数*/ 9 void *hello(void *arg) 10 { 11 printf("hello world "); 12 } 13 14 int main() 15 { 16 pthread_t pid = 0; 17 int ret = 0; 18 19 /*获得一个新的线程*/ 20 ret = pthread_create(&pid, NULL, hello, NULL); 21 if(ret < 0) { 22 perror("pthread_create"); 23 exit(EXIT_FAILURE); 24 } 25 26 /* 检查线程退出状态*/ 27 pthread_join(pid, NULL); 28 exit(EXIT_SUCCESS); 29 }
二:互斥锁
下面代码是主线程和工作线程共享用户的输入缓冲,主线程创建了工作线程用于统计用户输入的字符数,它们之间通过互斥锁保证对输入缓冲的访问不发生冲突;
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 #include <semaphore.h> 5 #include <string.h> 6 #define WORK_SIZE 1024 7 pthread_mutex_t work_mutex; 8 char work[1024]; /* 工作区*/ 9 int time_to_exit = 0; /*退出标志*/ 10 11 void *thread_function(void *arg); 12 13 14 int main() 15 { 16 int ret = 0; 17 pthread_t tid = 0; 18 void *thread_result; 19 20 /* 对互斥锁进行初始化*/ 21 ret = pthread_mutex_init(&work_mutex, NULL); 22 if(ret != 0) { 23 perror("mutex init failure"); 24 return 1; 25 } 26 27 ret = pthread_create(&tid, NULL, thread_function, NULL); 28 if(ret != 0) { 29 perror("pthread_create"); 30 return 1; 31 } 32 33 /*给工作区加上锁,把文本读到里面 34 然后给它解锁允许被其他线程访问*/ 35 pthread_mutex_lock(&work_mutex); 36 printf("Inpu some txt, Enter 'end' to finish "); 37 while(!time_to_exit) { 38 fgets(work, 1024, stdin); 39 pthread_mutex_unlock(&work_mutex); 40 41 while(1) { 42 pthread_mutex_lock(&work_mutex); 43 if(work[0] != '