먼저 예를 들어보겠습니다. 숫자를 증가시키기 위해 두 개의 스레드를 만듭니다. 이 예는 실용적인 가치가 없을 수도 있지만 약간만 변경하면 다른 곳에서도 사용할 수 있습니다.
코드:
/*thread_example.c : c multiple thread programming in linux *author : falcon *e-mail : tunzhj03@st.lzu.edu.cn */ #include <pthread.h> #include <stdio.h> #include <sys/time.h> #include <string.h> #define max 10 pthread_t thread[2]; pthread_mutex_t mut; int number=0, i; void *thread1() { printf ("thread1 : i'm thread 1/n"); for (i = 0; i < max; i++) { printf("thread1 : number = %d/n",number); pthread_mutex_lock(&mut); number++; pthread_mutex_unlock(&mut); sleep(2); } printf("thread1 :主函数在等我完成任务吗?/n"); pthread_exit(null); } void *thread2() { printf("thread2 : i'm thread 2/n"); for (i = 0; i < max; i++) { printf("thread2 : number = %d/n",number); pthread_mutex_lock(&mut); number++; pthread_mutex_unlock(&mut); sleep(3); } printf("thread2 :主函数在等我完成任务吗?/n"); pthread_exit(null); } void thread_create(void) { int temp; memset(&thread, 0, sizeof(thread)); //comment1 /*创建线程*/ if((temp = pthread_create(&thread[0], null, thread1, null)) != 0) //comment2 printf("线程1创建失败!/n"); else printf("线程1被创建/n"); if((temp = pthread_create(&thread[1], null, thread2, null)) != 0) //comment3 printf("线程2创建失败"); else printf("线程2被创建/n"); } void thread_wait(void) { /*等待线程结束*/ if(thread[0] !=0) { //comment4 pthread_join(thread[0],null); printf("线程1已经结束/n"); } if(thread[1] !=0) { //comment5 pthread_join(thread[1],null); printf("线程2已经结束/n"); } } int main() { /*用默认属性初始化互斥锁*/ pthread_mutex_init(&mut,null); printf("我是主函数哦,我正在创建线程,呵呵/n"); thread_create(); printf("我是主函数哦,我正在等待线程完成任务阿,呵呵/n"); thread_wait(); return 0; }
먼저 컴파일하고 실행해 보겠습니다.
인용:
falcon@falcon:~/program/c/code/ftp$ gcc -lpthread -o thread_example thread_example.c falcon@falcon:~/program/c/code/ftp$ ./thread_example 我是主函数哦,我正在创建线程,呵呵 线程1被创建 线程2被创建 我是主函数哦,我正在等待线程完成任务阿,呵呵 thread1 : i'm thread 1 thread1 : number = 0 thread2 : i'm thread 2 thread2 : number = 1 thread1 : number = 2 thread2 : number = 3 thread1 : number = 4 thread2 : number = 5 thread1 : number = 6 thread1 : number = 7 thread2 : number = 8 thread1 : number = 9 thread2 : number = 10 thread1 :主函数在等我完成任务吗? 线程1已经结束 thread2 :主函数在等我完成任务吗? 线程2已经结束
이제 위 소개와 관련된 여러 함수와 변수를 인터넷에서 인용하겠습니다.
인용:
스레드 관련 작업
一 pthread_t
pthread_t는 /usr/include/bits/pthreadtypes.h 헤더 파일에 정의되어 있습니다.
typedef unsigned long int pthread_t;
스레드의 식별자입니다.
두 번째 pthread_create
pthread_create 함수는 스레드를 생성하는 데 사용됩니다. 해당 프로토타입은 다음과 같습니다.
extern int pthread_create __p ((pthread_t *__thread, __const pthread_attr_t *__attr,
void *(*__start_routine) (void *), void * __arg ));
첫 번째 매개변수는 스레드 식별자에 대한 포인터이고, 두 번째 매개변수는 스레드 속성을 설정하는 데 사용되며, 세 번째 매개변수는 스레드 실행 함수의 시작 주소이고, 마지막 매개변수는 실행 매개변수입니다. 기능. 여기서 함수 스레드에는 매개변수가 필요하지 않으므로 마지막 매개변수는 널 포인터로 설정됩니다. 또한 두 번째 매개변수를 널 포인터로 설정하여 기본 속성을 가진 스레드를 생성합니다. 다음 섹션에서는 스레드 속성의 설정 및 수정에 대해 설명하겠습니다. 스레드가 성공적으로 생성되면 함수는 0을 반환합니다. 0이 아니면 스레드 생성이 실패합니다. 일반적인 오류 반환 코드는 eagain 및 einval입니다. 전자는 시스템이 새로운 스레드 생성을 제한한다는 것을 의미합니다. 예를 들어 스레드 수가 너무 많다는 것은 두 번째 매개변수가 나타내는 스레드 속성 값이 불법임을 의미합니다. 스레드가 성공적으로 생성된 후 새로 생성된 스레드는 매개변수 3과 매개변수 4에 의해 결정된 함수를 실행하고 원래 스레드는 계속해서 다음 코드 줄을 실행합니다.
3개의 pthread_join pthread_exit
pthread_join 함수는 스레드의 끝을 기다리는 데 사용됩니다. 함수 프로토타입은 다음과 같습니다.
extern int pthread_join __p ((pthread_t __th, void **__thread_return));
첫 번째 매개변수는 대기할 스레드 식별자이고, 두 번째 매개변수는 사용할 수 있는 사용자 정의 포인터입니다. 기다리고 있는 스레드의 반환 값을 저장합니다. 이 함수는 스레드 차단 함수입니다. 이를 호출하는 함수는 대기 스레드가 끝날 때까지 대기합니다. 함수가 반환되면 대기 스레드의 리소스가 복구됩니다. 스레드를 종료하는 방법에는 두 가지가 있습니다. 하나는 위의 예와 같으며, 함수가 종료되면 이를 호출한 스레드도 종료됩니다. 함수 프로토타입은 다음과 같습니다.
extern void pthread_exit __p ((void *__retval)) __attribute__ ((__noreturn__));
유일한 매개 변수는 pthread_join의 두 번째 매개 변수 thread_return이 null이 아닌 한 함수의 반환 코드입니다. 값은 thread_return으로 전달됩니다. 마지막으로 주의할 점은 여러 스레드가 하나의 스레드를 기다릴 수 없다는 것입니다. 그렇지 않으면 신호를 수신한 첫 번째 스레드가 성공적으로 반환되고 pthread_join을 호출하는 나머지 스레드는 오류 코드 esrch를 반환합니다.
이 섹션에서는 가장 간단한 스레드를 작성하고 가장 일반적으로 사용되는 세 가지 함수인 pthread_create, pthread_join 및 pthread_exit를 마스터했습니다. 다음으로 스레드의 몇 가지 일반적인 속성과 이를 설정하는 방법을 살펴보겠습니다.
Mutex 잠금 관련
Mutex 잠금은 일정 시간 내에 하나의 스레드만 코드 조각을 실행하도록 하는 데 사용됩니다.
一 pthread_mutex_init
pthread_mutex_init 함수는 뮤텍스 잠금을 생성하는 데 사용됩니다. null 매개변수는 기본 속성이 사용됨을 나타냅니다. 특정 속성에 대한 뮤텍스를 선언해야 하는 경우 pthread_mutexattr_init 함수를 호출해야 합니다. pthread_mutexattr_setpshared 함수와 pthread_mutexattr_settype 함수는 뮤텍스 잠금 속성을 설정하는 데 사용됩니다. 이전 함수는 pthread_process_private 및 pthread_process_shared의 두 값을 갖는 pshared 속성을 설정합니다. 전자는 서로 다른 프로세스의 스레드를 동기화하는 데 사용되고 후자는 이 프로세스에서 서로 다른 스레드를 동기화하는 데 사용됩니다. 위의 예에서는 기본 속성 pthread_process_private을 사용하고 있습니다. 후자는 뮤텍스 잠금 유형을 설정하는 데 사용됩니다. 선택적 유형은 pthread_mutex_normal, pthread_mutex_errorcheck, pthread_mutex_recursive 및 pthread _mutex_default입니다. 이들은 각각 다른 목록 및 잠금 해제 메커니즘을 정의합니다. 일반적인 상황에서는 마지막 기본 속성이 선택됩니다.
두 개의 pthread_mutex_lock pthread_mutex_unlock pthread_delay_np
pthread_mutex_lock 문은 뮤텍스 잠금으로 잠기기 시작합니다. 후속 코드는 pthread_mutex_unlock이 호출될 때까지 잠깁니다. 즉, 동시에 하나의 스레드에서만 호출하고 실행할 수 있습니다. 스레드가 pthread_mutex_lock을 실행할 때 이때 다른 스레드가 잠금을 사용하고 있으면 해당 스레드는 차단됩니다. 즉, 프로그램은 다른 스레드가 뮤텍스 잠금을 해제할 때까지 대기합니다.
참고:
1 위의 두 가지 휴면은 데모 목적일 뿐만 아니라 스레드가 일정 시간 동안 휴면 상태를 유지하여 스레드가 뮤텍스 잠금을 해제하고 다른 스레드가 이 잠금을 사용할 때까지 기다릴 수 있도록 하기 위한 것입니다. 이 문제는 아래 참고문헌 1에 설명되어 있습니다. 그런데 Linux에는 pthread_delay_np 함수가 없는 것 같아서(해봤는데 정의된 함수에 대한 참조가 없다는 메시지가 표시됨) 대신 sleep을 사용했습니다. 그러나 참조 2에는 다른 방법이 나와 있는 것 같습니다. 이를 달성하는 방법을 제공하는 pthread_cond_timedwait로 대체되었습니다.
2 안에 있는 댓글 1~5를 주목해 주세요. 그것이 제가 알아내는 데 몇 시간이 걸린 문제입니다.
comment1, comment4, comment5가 없으면 pthread_join 시 segfault가 발생하므로, 위의 comment2, comment3이 근본 원인이므로 반드시 전체 코드를 작성해 주시기 바랍니다. 위의 스레드가 성공적으로 생성되지 않을 수 있으므로 스레드가 끝날 때까지 기다릴 수 없으며 pthread_join 사용 시 분할 오류(알 수 없는 메모리 영역에 접근)가 발생합니다. 게다가 memset을 사용할 때 string.h 헤더 파일을 포함시켜야 합니다
위 내용은 Linux 다중 스레드 프로그래밍 예제 코드 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!