一. 线程
1. 基本函数
a. 关于pthread_id
-
/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h:
-
typedef unsigned long int pthread_t;
定义为unsigned long int,这样打印时就可以用%u来打印了
b. 线程创建函数
线程函数都在:/usr/include/pthread.h中
-
extern int pthread_create (pthread_t *__restrict __newthread,
-
const pthread_attr_t *__restrict __attr,
-
void *(*__start_routine) (void *),
-
void *__restrict __arg) __THROWNL __nonnull ((1, 3));
arg1: 值传递,获取了新创建的线程id
arg2: 线程的属性
arg3: 线程回调函数
arg4: 回调函数的参数
c.进程等侍线程结束
-
extern int pthread_join (pthread_t __th, void **__thread_return);
线程是依赖于进程存在的,一旦进制结束就没线程什么事了。
为了防止进制结束时,还有线程要执行,需要等侍线程结束
这个等侍函数就是pthread_join
d. 获取线程id
-
extern pthread_t pthread_self (void) __THROW __attribute__ ((__const__));
注意:只有在线性的回调函数中调用才可以获取id,在main函数中是main的thread_id
2. 创建线程
2.1.1 创建线程不带参数
-
cong@msi:/work/test/thread/1start$ cat start.c
-
#include "utils.h"
-
-
void* thread_routine(void* arg)
-
{
-
dbmsg("%u",(unsigned int)pthread_self());
-
return NULL;
-
}
-
int main ( int argc, char *argv[] )
-
{
-
pthread_t thread_id;
-
void* thread_result;
-
int status;
-
//创建线程: 无属性设置,回调是thread_routine,无参数
-
status = pthread_create(&thread_id, NULL, thread_routine, NULL);
-
if(status != 0)
-
{
-
dbmsg("%s",strerror(errno));
-
return -1;
-
}
-
dbmsg("%u", (unsigned int)thread_id);
-
-
status = pthread_join(thread_id, &thread_result); //等侍线程执行结束
-
if( status != 0)
-
{
-
dbmsg("%s", strerror(errno));
-
return -1;
-
}
-
-
if(thread_result == NULL)
-
return 0;
-
return EXIT_SUCCESS;
-
}
1start.rar (下载后改名为1start.rar)
2.1.2 创建线程带参数
-
cong@msi:/work/test/thread/1start$ cat start.c
-
#include "utils.h"
-
-
void* thread_routine(void* arg)
-
{
-
printf("%s", (char*) arg); //打印参数
-
return NULL;
-
}
-
-
int main ( int argc, char *argv[] )
-
{
-
pthread_t thread_id;
-
char buf[1024]= "hello,world\n";
-
//创建线程: 将buf用为参数
-
pthread_create(&thread_id, NULL, thread_routine, (void*)buf);
-
-
pthread_join(thread_id, NULL);
-
-
return EXIT_SUCCESS;
-
}
cong@msi:/work/test/thread/1start$ ./start
hello,world
2.2 线程退出
-
cong@msi:/work/test/thread/2exit$ cat exit.c
-
#include "utils.h"
-
-
void* thread_routine(void* arg)
-
{
-
dbmsg("%u",(unsigned int)pthread_self());
-
return ((void*)2); //将线程结束值返回
-
}
-
-
int main ( int argc, char *argv[] )
-
{
-
pthread_t thread_id;
-
void* thread_result;
-
int status;
-
//创建线程: 无属性设置,回调是thread_routine,无参数
-
status = pthread_create(&thread_id, NULL, thread_routine, NULL);
-
-
status = pthread_join(thread_id, &thread_result); //等侍线程结束,结束时返回值放在thread_result中
-
-
dbmsg("thread exit code=%d", (int)thread_result); //打印看一下
-
-
return EXIT_SUCCESS;
-
}
cong@msi:/work/test/thread/2exit$ ./exit
exit.c:main[19]: thread exit code=2 -->就是这个
2exit.rar (下载后改名为3mutex.tar.gz)
2.3 锁
a.不明显但不等于不存在
两个线程同时访问一个数据时,要加锁
-
cong@msi:/work/test/thread/3mutex$ cat mutex.c
-
#include "utils.h"
-
int globle; //要保护的全局变量
-
pthread_mutex_t thread_mutex;
-
-
void* thread_routine(void* arg)
-
{
-
pthread_mutex_lock(&thread_mutex); //2.上锁
-
globle ++; //把要保护的数据放中间
-
dbmsg("globle=%d",globle);
-
pthread_mutex_unlock(&thread_mutex); //3.解锁
-
return ((void*)2);
-
}
-
-
int main ( int argc, char *argv[] )
-
{
-
pthread_t thread_id1;
-
pthread_t thread_id2;
-
void* thread_result;
-
int status;
-
-
globle = 1;
-
pthread_mutex_init(&thread_mutex, NULL); //1.初始化锁
-
-
status = pthread_create(&thread_id1, NULL, thread_routine, NULL);
-
status = pthread_create(&thread_id2, NULL, thread_routine, NULL);
-
-
status = pthread_join(thread_id1, &thread_result);
-
status = pthread_join(thread_id2, &thread_result);
-
-
return EXIT_SUCCESS;
-
}
结果:
cong@msi:/work/test/thread/3mutex$ ./mutex
mutex.c:thread_routine[9]: globle=2
mutex.c:thread_routine[9]: globle=3
b.来个明显的
b.1 第1个线程运行时,在回调函数中产生一个局部变量buf_1指向参数buf1的首地址,
获取锁,进行打印
b.2 此时第2个线程开始运行,在回调函数中产生一个局部变量buf_2指向参数buf1的首地址,
获取不了锁,不能进行打印,一直在等侍线程1运行结束释放锁
b.3然后线程2开始打印
b.4 如果没有锁时,就会出乱子
-
cong@msi:/work/test/thread/3mutex$ cat ./mutex.c
-
#include "utils.h"
-
pthread_mutex_t thread_mutex;
-
-
void* thread_routine(void* arg)
-
{
-
char* buf = (char*) arg;
-
//pthread_mutex_lock(&thread_mutex); //加上锁之后就不存在问题了
-
while(*buf != '\0')
-
{
-
printf("%c", *buf);
-
buf++;
-
}
-
printf("\n");
-
//pthread_mutex_unlock(&thread_mutex);
-
return NULL;
-
}
-
-
int main ( int argc, char *argv[] )
-
{
-
pthread_t thread_id1;
-
pthread_t thread_id2;
-
void* thread_result;
-
int status;
-
int i;
-
char buf1[1024];
-
char buf2[1024];
-
for(i=0;i<1023; i++)
-
{
-
buf1[i] = 'a';
-
buf2[i] = 'b';
-
}
-
buf1[1023] = '\0';
-
buf2[1023] = '\0';
-
-
-
pthread_mutex_init(&thread_mutex, NULL);
-
-
status = pthread_create(&thread_id1, NULL, thread_routine, (void*)buf1);
-
status = pthread_create(&thread_id2, NULL, thread_routine, (void*)buf2);
-
-
status = pthread_join(thread_id1, &thread_result);
-
status = pthread_join(thread_id2, &thread_result);
-
-
return EXIT_SUCCESS;
-
}
结果:
-
cong@msi:/work/test/thread/3mutex$ ./mutex -->第1次执行没有出现问题
-
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-
cong@msi:/work/test/thread/3mutex$ ./mutex -->第2次执行发现出问题了,这跟等公交车一样,不等车时一个接一个的车来了,真要等车时车反而不来了
-
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbabaaaaabaaabaaaabaaaabaaaabaaaabaaaabaaaabaaaabaaaabaaaabaaaabaaaabaaaabaaaababbabababaaabaaaabbbabbbbbabbbbbabbbbabbbbabbbbabaaaabaaaabaaaaabaaaabaaaabababaaaabaaaababababbbababaabaaaabaaaababababbbbbabbabaaaabaaaababababbbbabaababbbbabaaababbbabababaaaaabababaaaababbbabbbbabbbbabaaaababababbbbabbbbaaaabaaaabaaaababbabbbbabababbbbaaababababbbbabaaaababababbbbaaaabaaababbbbabaaaaabaaaababbbbabbbbabbbbabaaaababababaaaabbbaaababbbbabbbbbabbbbabbbbbabbbbabbbbabbbbabbbbabaaaababababbbbabababbbbabbbbabababbbbabbbbabbbbbabbbbabbbbaaaababbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbababbbbabababababababbbbabbbababbbbabaaaababababbbbabbbbabababaaaababbabaaaabaaababbbbbabbbbabaaaababbabaaaababbbbabaaaababbbbabbbbbabbbbbabbbbbabbbbbabbbbbabbbbabaaaababbbbabaaaababababbbbabaaaabaaaababbbbabbbbabaaaababbabbbbabbbbabababaaaababbabbbbaaabaaaababaabaaaababbbbabbbbababababababababbbbababbabbbbabababaaababbbbabaaaababbabbbbabaaaababbabaaaababbabbbbabaaaaabaaaababaabaaaaabaaababbbbababbabbbbabaabaaaaabaaaababbabbbbabaaaababbabbbbabaaaabaaaababaabababaaaababbbbabbbbabaaaababaabababaaaababaababbabbbbbabbbbabbbbabaaaababaababbabaaaabaaaaabaaaababaababbabababbbbabababaaaabaaaababbbbabababaaaaabaaaaababababbbbabbbbbabbbbabbbbabbbbabaaaababaababbbababbbbabaaaababbbbabaaaababaabaaa
-
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
3mutex.rar (下载后改名为3mutex.tar.gz)
阅读(1350) | 评论(0) | 转发(0) |