linux下c语言多线程实例

本文通过几个例子演示linux下c语言是如何进行多线程操作的。

创建线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
pthread_t ntid;
void printids(const char *s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
printf("%s pid %u tid %u(0x%x)\n", s,
(unsigned int)pid, (unsigned int)tid, (unsigned int)tid);
}
void *thr_fn(void *arg)
{
printids(arg);
return NULL;
}
int main(void)
{
int err;
err = pthread_create(&ntid, NULL, thr_fn, "new thread: ");
if (err != 0) {
fprintf(stderr, "can't create thread: %s\n", strerror(err));
exit(1);
}
printids("main thread:");
sleep(1);
return 0;
}

取消线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
void *thr1(void *arg)
{
printf("thread 1 running\n");
return (void*)1;
}
void *thr2(void *arg)
{
printf("thread 2 running\n");
pthread_exit((void*)2);
return NULL;
}
void *thr3(void *arg)
{
int i;
for (i = 0; i < 5; i++) {
printf("thread 3 running\n");
sleep(1);
}
return NULL;
}
int main(void)
{
pthread_t t1, t2, t3;
void *tret;
pthread_create(&t1, NULL, thr1, NULL);
pthread_join(t1, &tret);
printf("thread 1 exit code: %d\n", (int)tret);
pthread_create(&t2, NULL, thr2, NULL);
pthread_join(t2, &tret);
printf("thread 2 exit code: %d\n", (int)tret);
pthread_create(&t3, NULL, thr3, NULL);
sleep(3);
pthread_cancel(t3);
pthread_join(t3, &tret);
printf("thread 3 exit code: %d\n", (int)tret);
return 0;
}

互斥体mutex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NLOOP 5000
int counter;
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
void *doit(void*);
int main(void)
{
pthread_t t1, t2;
pthread_create(&t1, NULL, doit, NULL);
pthread_create(&t2, NULL, doit, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}
void *doit(void *arg)
{
int i, val;
for (i = 0; i < NLOOP; i++) {
pthread_mutex_lock(&counter_mutex);
val = counter;
printf("%x: %d\n", (unsigned int)pthread_self(), val+1);
counter = val+1;
pthread_mutex_unlock(&counter_mutex);
}
return NULL;
}

条件变量cond

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct msg {
struct msg *next;
int num;
};
struct msg *head;
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void *consumer(void *p)
{
struct msg *mp;
for (;;) {
pthread_mutex_lock(&lock);
while (head == NULL)
pthread_cond_wait(&has_product, &lock);
mp = head;
head = mp->next;
pthread_mutex_unlock(&lock);
printf("consume %d\n", mp->num);
free(mp);
sleep(rand()%5);
}
return NULL;
}
void *producer(void *p)
{
struct msg *mp;
for (;;) {
mp = malloc(sizeof(struct msg));
mp->num = rand()%1000 + 1;
printf("produce %d\n", mp->num);
pthread_mutex_lock(&lock);
mp->next = head;
head = mp;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&has_product);
sleep(rand()%5);
}
return NULL;
}
int main(void)
{
pthread_t pid, cid;
srand(time(NULL));
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
return 0;
}

信号量semaphore

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM 5
int queue[NUM];
sem_t blank_num, product_num;
void *producer(void *arg)
{
int p = 0;
while (1) {
sem_wait(&blank_num);
queue[p] = rand()%1000+1;
printf("produce %d\n", queue[p]);
sem_post(&product_num);
p = (p+1)%NUM;
sleep(rand()%5);
}
}
void *consumer(void *arg)
{
int c = 0;
while (1) {
sem_wait(&product_num);
printf("consume %d\n", queue[c]);
queue[c] = 0;
sem_post(&blank_num);
c = (c+1)%NUM;
sleep(rand()%5);
}
}
int main(void)
{
pthread_t pid, cid;
sem_init(&blank_num, 0, NUM);
sem_init(&product_num, 0, 0);
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
sem_destroy(&blank_num);
sem_destroy(&product_num);
return 0;
}