一、线程概念
如果进程需要完成多个任务的时候,需要对其进行串行化操作。而如果其中一个任务(比如io操作),造成任务执行的挂起。则可以分解任务,将任务分开执行。
其中的每个任务就是所谓的线程。
线程包含了表示进程内执行环境必需的信息。
进程的所有信息对该进程的所有线程都是共享的。包括可执行的程序文本、程序的全局内存和堆内存、栈以及文件描述符。
二、线程创建
新增的线程可以通过pthread_create()函数来创建。
pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void*), void*restrict arg );
当pthread_create成功返回时,由tidp指向的内存单元被设置为新创建线程的线程ID,attr参数用于定制各种不同的线程
属性。新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg,如果需要向start_rtn函数传递
的参数不止一个,需要把这些参数放到一个结构体中,然后作为arg参数传入。
在linux下(gcc -pthread -o 文件名 可执行文件名 )进行编译
线程创建的时候并不能保证哪个线程会先运行。
#include <stdio.h> #include <stdlib.h> #include <pthread.h> void thread(void) { int i; sleep(1); for(i=0;i<10;i++) printf("This is a pthread.\n"); } int main(void) { pthread_t id; int i,ret; ret=pthread_create(&id,NULL,(void *) thread,NULL); // sleep(1); if(ret!=0){ printf ("Create pthread error!\n"); exit (1); } for(i=0;i<3;i++) printf("This is the main process.\n"); // pthread_join(id,NULL); pthread_exit(NULL); return (0); }
三、线程同步
当多个控制线程共享相同的内存的时候,需要确保每个线程看到一致的数据视图。
为了解决数据同步的问题,线程使用锁,也就是在同一时间只允许一个 线程访问该变量。
1、互斥量
我们可以通过使用pthread的互斥接口保护数据,确保同一时间只有一个线程访问数据。
互斥变量用pthread_mutex_t数据类型来表示。
对数据量加锁需要调用pthread_mutex_lock
对互斥量解锁,需要调用pthread_mutex_unlock
下面的代码没有经过加锁,应该是1和2连续输出的,但现在运行到一半时候可能被另一个线程打进来。
#include <stdio.h> #include <pthread.h> #include <malloc.h> #include <string.h> void* th_func(void* arg){ int i; for(i=0; i<5; i++){ printf("1\n"); sleep(1); printf("2\n"); } } int main(void){ int ret; pthread_t tid1,tid2; ret = pthread_create(&tid1, NULL, th_func, NULL); if(ret != 0){ printf("pthread_create:%s\n",strerror(ret)); return -1; } ret = pthread_create(&tid2, NULL, th_func, NULL); if(ret != 0){ printf("pthread_create:%s\n",strerror(ret)); return -1; } sleep(15); return 0; }
1 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 2
如果加上线程锁之后:
就避免了以上现象的发生。
- #include <stdio.h>
- #include <pthread.h>
- #include <malloc.h>
- #include <string.h>
- pthread_mutex_t *mutex;
- void* th_func(void* arg){
- int i;
- for(i=0; i<5; i++){
- pthread_mutex_lock(mutex);
- printf("1\n");
- sleep(1);
- printf("2\n");
- pthread_mutex_unlock(mutex);
- }
- }
- int main(void){
- int ret,result = 0;
- pthread_t tid1,tid2;
- mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
- if(mutex == NULL){
- perror("malloc");
- result = -1;
- goto FINALLY;
- }
- pthread_mutex_init(mutex,NULL);
- ret = pthread_create(&tid1, NULL, th_func, NULL);
- if(ret != 0){
- printf("pthread_create:%s\n",strerror(ret));
- result = -1;
- goto FINALLY;
- }
- ret = pthread_detach(tid1);
- if(ret != 0){
- printf("pthread_detach:%s\n",strerror(ret));
- result = -1;
- goto FINALLY;
- }
- ret = pthread_create(&tid2, NULL, th_func, NULL);
- if(ret != 0){
- printf("pthread_create:%s\n",strerror(ret));
- result = -1;
- goto FINALLY;
- }
- ret = pthread_detach(tid2);
- if(ret != 0){
- printf("pthread_detach:%s\n",strerror(ret));
- result = -1;
- goto FINALLY;
- }
- sleep(15);
- FINALLY:
- if(mutex != NULL){
- pthread_mutex_destroy(mutex);
- free(mutex);
- }
- return result;
- }
版权声明:本文为博主原创文章,未经博主允许不得转载。