多线程

<!-- @page { margin: 2cm } PRE { font-family: "AR PL UKai CN" } P { margin-bottom: 0.21cm } -->

多线程

-、主要函数:

二、

1、cpu调度的基本单位是线程。线,进程对于kernel而言没有什么区别,在内核里有相应的task_struct(任务描述符)

线程与进程:1)调度一样2)线程的创建成本会快一些

2、线程,地址空间是共享的

pthread_self();

pthread_create();

pthread_exit(NULL);

pthread_join(tid,NULL);

创建多个线程: pthread tid[5] ; pthread_create(tid+i,NULL,thread_handler,NULL);

用堆分配,不要用栈,用栈不保险。

栈-->私有,只要函数退出,栈的东西就没有了,所以尽量不要返回栈里的东西的地址!

线程有点普通函数的感觉。线程共享文件描述符表。

3、线程锁

1)初始化:动态/静态

2)lock,unlock

3)消毁一把锁

lock代码段,加锁的目的,保护数据

锁应是一个全局变量。全局锁-----互斥锁

如果已锁,你再去lock,那么会使你阻塞,不占用cpu



FILE* fp=fdopen(fd,”r+”);将fd转换成FILE*型

4、线程的条件变量

在修改全局变量的地方加锁,完了后解锁,发信号

pthread_cond_wait(&g_cond,&g_lock)解锁、休眠;被唤醒后,加锁、执行(原子操作)



signal:只是唤醒某一个线程

broadcast:所有线程都会起来

5、线程的分离属性

1)创建的时候就设置其为分离属性2)用pthread_detach()自己分离属性

pthread_attr_init(&attr)将attr初始化为默认属性

pthread_attr_setdetach()设置分离



设成分离属性后就不能----join了

三、例程

1、

/*pthread_create.c*/

#include <pthread.h>

#include <string.h>

#include <stdio.h>

#include <stdlib.h>



void *thread_handler(void *arg)

{

printf("pid=%d/n", getpid());

//exit(0);

while (1)

sleep(1);

return NULL;

}



int main(void)

{

pthread_t tid;

int ret;



ret = pthread_create(&tid, NULL, thread_handler,

NULL);

if (ret) {

printf("%s/n", strerror(ret));

exit(1);

}

while (1)

sleep(1);

printf("pid=%d/n", getpid());

//}

exit(0);

}

2、

/*pthread_exit.c*/

#include <pthread.h>

#include <string.h>

#include <stdio.h>

#include <stdlib.h>



void *thread_handler(void *arg)

{

printf("pid=%d/n", getpid());

pthread_exit(NULL);

}



int main(void)

{

pthread_t tid;

int ret;



ret = pthread_create(&tid, NULL, thread_handler,

NULL);

if (ret) {

printf("%s/n", strerror(ret));

exit(1);

}

pthread_exit(NULL);

}

3、

/*pthread_join.c*/

#include <pthread.h>

#include <string.h>

#include <stdio.h>

#include <stdlib.h>



static int mul=0;



void *thread_handler(void *arg)

{

char buf[5];

bzero(buf, 5);

write(1, "Please input mul: ", 19);

read(0, buf, 4);

mul =atoi(buf);

return NULL;

// pthread_exit(NULL);

}



int main(void)

{

pthread_t tid;

int ret;



ret = pthread_create(&tid, NULL, thread_handler,

NULL);

if (ret) {

printf("%s/n", strerror(ret));

exit(1);

}

while (1)

ret++;

pthread_join(tid, NULL);

printf("ret=%d/n", 5*mul);

pthread_exit(NULL);

}

/*可用return NULL代替pthread_exit(NULL)*/

4、

/*创建5个线程*/

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <pthread.h>

#include <string.h>



void *thread_handler(void *arg)

{

// int value = *((int *)(arg));

int value = (int)arg;

printf("value=%d/n", value);

return NULL;

}



int main(void)

{

int i, ret;

pthread_t tid[5];

int *a = (int *)malloc(5*sizeof(int));



for (i = 0; i < 5; i++) {

// a[i] = i;

ret = pthread_create(tid+i, NULL,

thread_handler, (void *)i);// (void *)i玩无间道,欺骗编译器。本来i是int型的,将其当作(void*)型传进去.



if (ret) {

printf("%s/n", strerror(ret));

exit(1);

}

}

pthread_exit(NULL);

for(i = 0; i < 5; i++) {

pthread_join(tid[i], NULL);

}

free(a);

pthread_exit(NULL);

}

5、

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <unistd.h>

#include <string.h>

#include <pthread.h>



int fd;



void *thread_handler(void *arg)

{

close(fd);

return NULL;

}



int main(void)

{

pthread_t tid;

int ret;

char buf[100];

ret = pthread_create(&tid, NULL,

thread_handler, NULL);

if (ret) {

printf("%s/n", strerror(ret));

exit(1);

}



fd = open("/etc/passwd", O_RDONLY);

if (fd == -1) {

perror("open");

exit(1);

}

pthread_join(tid, NULL);

ret = read(fd, buf, 100);

if (ret == -1) {

perror("read");

exit(1);

}

write(1, buf, ret);

pthread_exit(NULL);

}

/*线程共享很多东西*/

6、

/*线程锁(互斥)*/

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <unistd.h>

#include <string.h>

#include <pthread.h>



int fd;



pthread_mutex_t glock;//用全局锁,同一时刻只能由一个线程上锁



void *thread_handler(void *arg)

{

char buf[20];



pthread_mutex_lock(&glock);

lseek(fd, 0, SEEK_SET);

FILE *fp = fdopen(fd, "r+");//将fd转换成FILE*型

if (fp == NULL) {

perror("fdopen");

exit(1);

}



fgets(buf, 20, fp);

printf("%s", buf);

lseek(fd, 0, SEEK_SET);



pthread_mutex_unlock(&glock);

return NULL;

}



void main_thread_work(void)

{

pthread_mutex_lock(&glock);

lseek(fd, 0, SEEK_SET);

int i = 0;

char buf[3];

while (1) {//写0,1,2,3,4,5,6,7,8,9

sprintf(buf, "%d/n", i++);//'/n'也是占一个字符!

if (strlen(buf) == 3)

break;

write(fd, buf, 2);

sleep(2);

}

pthread_mutex_unlock(&glock);

}



int main(void)

{

pthread_t tid;

int ret;

char buf[100];



pthread_mutex_init(&glock, NULL);//构造一个互斥,生成一个互斥锁glock



ret = pthread_create(&tid, NULL,

thread_handler, NULL);

if (ret) {

printf("%s/n", strerror(ret));

exit(1);

}



fd = open("tmp", O_RDWR | O_CREAT | O_TRUNC,

0777);

if (fd == -1) {

perror("creat");

exit(1);

}



main_thread_work();

pthread_exit(NULL);

}

7、

/*条件变量*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>

#include <fcntl.h>

#include <unistd.h>



long long g_value;

#define THREADNUM 5

#define BASE 300000000



pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;//锁静态初始化

pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;//条件变量静态初始化



static void do_prime()

{

long long i;

int flag = 0;

for (i = 2; i < g_value; i++) {

if (g_value % i == 0) {

flag = 1;

break;

}

}

if (flag == 0) {

printf("%lld is a prime!/n", g_value);

} else

printf("%lld is not a prime!/n", g_value);

}



void *thread_handler(void *arg)

{

while (1) {

pthread_mutex_lock(&g_lock);

pthread_cond_wait(&g_cond, &g_lock);//上来先解锁,休眠;被唤醒后,加锁,往下执行

do_prime();

pthread_mutex_unlock(&g_lock);

}

return NULL;

}



int main(void)

{

int i, ret, value;

pthread_t tid[5];



for (i = 0; i < THREADNUM; i++) {

ret = pthread_create(tid+i, NULL,

thread_handler, NULL);

if (ret) {

printf("%s/n", strerror(ret));

exit(1);

}

}



while (1) {

printf("Please input the prime:");

fflush(stdout);



scanf("%d", &value);

pthread_mutex_lock(&g_lock);

g_value = BASE + value;

pthread_mutex_unlock(&g_lock);

pthread_cond_signal(&g_cond);//对保护部分处理完后,发信号//signal只是唤醒某一个线程



}

}

8、

/*broadcast.c*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>

#include <fcntl.h>

#include <unistd.h>



long long g_value;

#define THREADNUM 5

#define BASE 300000000



pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;



static void do_prime()

{

long long i;

int flag = 0;

for (i = 2; i < g_value; i++) {

if (g_value % i == 0) {

flag = 1;

break;

}

}

if (flag == 0) {

printf("%lld is a prime!/n", g_value);

} else

printf("%lld is not a prime!/n", g_value);

}



void *thread_handler(void *arg)

{

pthread_mutex_lock(&g_lock);

pthread_cond_wait(&g_cond, &g_lock);

pthread_mutex_unlock(&g_lock);

printf("I am %d, exit!/n", (int)arg);

return NULL;

}



int main(void)

{

int i, ret, value;

pthread_t tid[5];



for (i = 0; i < THREADNUM; i++) {

ret = pthread_create(tid+i, NULL,

thread_handler, (void *)i);

if (ret) {

printf("%s/n", strerror(ret));

exit(1);

}

}

sleep(3);

//pthread_cond_signal(&g_cond);

pthread_cond_broadcast(&g_cond);

pthread_exit(NULL);

}

/*pthread_cond_signal(&g_cond);pthread_cond_broadcast(&g_cond);

signal: 只是唤醒某一个线程,谁先抢到就是谁的。

broadcast:所有线程都会起来

*/

9、/*attr.c*//*分离属性*/

#include <pthread.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>



void *thread_handler(void *arg)

{

pthread_detach(pthread_self());

sleep(5);

return NULL;

}



int main(void)

{

pthread_attr_t attr;

pthread_t tid;



pthread_attr_init(&attr);



// pthread_attr_setdetachstate(&attr,

// PTHREAD_CREATE_DETACHED);



int ret = pthread_create(&tid, &attr,

thread_handler, NULL);

if (ret) {

fprintf(stderr, "%s/n", strerror(ret));

exit(1);

}

#if 1

usleep(10);

printf("join!/n");

ret = pthread_join(tid, NULL);

if (ret) {

fprintf(stderr, "%s/n", strerror(ret));

pthread_exit(NULL);

}

printf("join!/n");

#endif

pthread_attr_destroy(&attr);

pthread_exit(NULL);

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值