Linux多线程与同步

来源:互联网 发布:电子目录制作软件 编辑:程序博客网 时间:2024/06/04 18:56

**

Linux多线程与同步:

**
Linux多线程与同步知识点参考下篇文章
作者:Vamei 出处:http://www.cnblogs.com/vamei

线程创建

1、在进程中只有一个控制进程。
2、程序开始运行时每个进程只有一个线程,以单线程方式启动。在创建多个线程以前,进程的行为与传统的进程没有区别。
3、gcc链接时加 -pthread (加在末尾) 链接libpthread.so库(该库时系统的)。
4、创建一个线程调用pthread_create函数。(启动线程)
ldd thr(执行文件名) 此命令可以查看thr这个执行文件相关的库。

线程终止

1、任一线程调用exit函数,整个线程就会终止。
2、信号默认动作是终止进程的,任一线程如接收到此信号,整个进程会终止。(所以要特别注意的是:信号捕捉只写在主线程中,其他线程不写,否则代码维护特别复杂。)
3、单线程退出有三种方式:
1)线程只是从启动函数返回,返回值是线程的退出码。(return的方式)
2)线程可以被同一进程中其他线程取消。 (pthread_cancel)
3)线程调用pthread_exit(voic*) , 可以得到线程的返回值。

线程被分离

使用方法:

 int pthread_detach(pthread_t thread);//使线程处于被分离状态

使用场景:
1、主线程不需要等待子线程
2、主线程不关心子线程的返回码
注意点:
1、对于被分离状态的线程,不需要调用pthread_join等待线程退出。如果其他线程调用了pthread_join,则会失败,返回EINVAL。
2、一个线程不能自己调用pthread_detach改变自己为被分离状态,只能由其他线程调用pthread_detach。

linux多线程常用函数介绍:

http://blog.chinaunix.net/uid-29924858-id-4609393.html
此网站有常用函数使用例子

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,                     void *(*start_routine) (void *), void *arg);

返回值:若是成功建立线程返回0,否则返回错误的编号
形式参数:
pthread_t *thread—— 要创建的线程的线程id指针
const pthread_attr_t *attr—— 创建线程时的线程属性
void (*start_routine) (void ) —— 返回值是void类型的指针函数
void *arg —— start_routine 的行参
进行链接的时候要加上-lpthread

int pthread_join(pthread_t thread, void **retval);

功能:pthread_join()函数,以阻塞的方式等待thread指定的线程结束
说明:当函数返回时,被等待线程的资源被收回。如果进程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。参数含义如下:thread:
线程标识符,即线程ID,标识唯一线程,retval: 用户定义的指针,用来存储被等待线程的返回值,成功时返回0, 失败时返回的则是错误号。可以用于检查?
代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。

 pthread_t pthread_self(void);

功能:获取当前调用线程的 thread identifier(标识号)
说明:pthread_t的类型为unsigned long int,所以在打印的时候要使用%lu方式,否则将产生神奇的结果。

void  pthread_exit(void  *retval)

功能:使用函数pthread_exit退出线程,这是线程的主动行为;由于一个进程中的多个线程是共享数据段的,因此通常在线程退出之后,退出线程所占用的资源并不会随着线程的终止而得到释放,但是可以用pthread_join()函数来同步并释放资源。
说明:retval:pthread_exit()调用线程的返回值,可由其他函数如pthread_join来检索获取。

实例

1、利用多线程与有名管道技术,实现两个进程之间发送即时消息,实现聊天功能。

/* ============================================================================ Name        : 双向聊天.c Author      : Allen Version     : Copyright   : Your copyright notice Description : Hello World in C, Ansi-style ============================================================================ */#include <stdio.h>#include <stdlib.h>#include<string.h>#include <unistd.h>#include<errno.h>#include<pthread.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>void *readfifo_client1(){    int fd = open("/home/vicent/7/fifo1", O_RDONLY);    if (fd == -1)    {        printf("open failed : %s\n", strerror(errno));    }    char buf[1024];    memset(buf, 0, sizeof(buf));    int len = 0;    while ((len = read(fd, buf, sizeof(buf))) > 0)    {        printf("%s", buf);        memset(buf, 0, sizeof(buf));    }    close(fd);    return NULL;}void *writefifo_client1(){    int fd = open("/home/vicent/7/fifo2", O_WRONLY);    if (fd == -1)    {        printf("open failed : %s\n", strerror(errno));    }    char buf[1024];    memset(buf, 0, sizeof(buf));    while (1)    {        memset(buf, 0, sizeof(buf));        read(STDIN_FILENO, buf, sizeof(buf));        write(fd, buf, sizeof(buf));    }    close(fd);    return NULL;}int main(){    pthread_t thd_1, thd_2;    if (pthread_create(&thd_1, NULL, readfifo_client1, NULL) != 0)    {        printf("error is %s\n", strerror(errno));    }    if (pthread_create(&thd_2, NULL, writefifo_client1, NULL) != 0)    {        printf("error is %s\n", strerror(errno));    }    pthread_join(thd_1, NULL);    pthread_join(thd_2, NULL);    return 0;}
/* * client2.c * *  Created on: 2016年10月17日 *      Author: Allen */#include <stdio.h>#include <stdlib.h>#include<string.h>#include <unistd.h>#include<pthread.h>#include<errno.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>void *readfifo_client2(){    int fd = open("/home/vicent/7/fifo2", O_RDONLY);    if (fd == -1)    {        printf("open failed : %s\n", strerror(errno));    }    char buf[1024];    memset(buf, 0, sizeof(buf));    int len = 0;    while ((len = read(fd, buf, sizeof(buf))) > 0)    {        printf("%s", buf);        memset(buf, 0, sizeof(buf));    }    close(fd);    return NULL;}void *writefifo_client2(){    int fd = open("/home/vicent/7/fifo1", O_WRONLY);    if (fd == -1)    {        printf("open failed : %s\n", strerror(errno));    }    char buf[1024];    memset(buf, 0, sizeof(buf));    while (1)    {        memset(buf, 0, sizeof(buf));        read(STDIN_FILENO, buf, sizeof(buf));        write(fd, buf, sizeof(buf));    }    close(fd);    return NULL;}int main(){    pthread_t thd_1, thd_2;    if (pthread_create(&thd_1, NULL, readfifo_client2, NULL) != 0)    {        printf("error is %s\n", strerror(errno));    }    if (pthread_create(&thd_2, NULL, writefifo_client2, NULL) != 0)    {        printf("error is %s\n", strerror(errno));    }    pthread_join(thd_1, NULL);    pthread_join(thd_2, NULL);    return 0;}

makefile

.SUFFIXES: .c .oCC=gccSRCS1=client1.cSRCS2=client2.cOBJS1=$(SRCS1:.c=.o)OBJS2=$(SRCS2:.c=.o)EXEC1=client1EXEC2=client2all: $(OBJS1) $(OBJS2)    $(CC) -o $(EXEC1) $(OBJS1) -lpthread    $(CC) -o $(EXEC2) $(OBJS2) -lpthread    @echo '-------------ok--------------'.c.o:     $(CC) -Wall -g -o $@ -c $<clean:    rm -f $(OBJS1)    rm -f $(OBJS2)    rm -f core*

结果
这里写图片描述

这里写图片描述

0 0