//创建多线程
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.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));;
}
printids("main thread:");
sleep(1);
return 0;
}
//pthread_join
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void *thr_fn1(void *arg)
{
printf("thread 1 returning\n");
return (void*)1;
}
void *thr_fn2(void *arg)
{
printf("thread 2 exiting\n");
pthread_exit((void*)2);
}
void *thr_fn3(void *arg)
{
while(1)
{
printf("thread 3 writing\n");
sleep(1);
}
}
int main(void)
{
pthread_t tid;
void *tret;
pthread_create(&tid, NULL, thr_fn1, NULL);
pthread_join(tid, &tret);
printf("thread 1 exit code %d\n", (int)tret);
pthread_create(&tid, NULL, thr_fn2, NULL);
pthread_join(tid, &tret);
printf("thread 2 exit code %d\n", (int)tret);
pthread_create(&tid, NULL, thr_fn3, NULL);
sleep(3);
pthread_cancel(tid);
pthread_join(tid, &tret);
printf("thread 3 exit code %d\n", (int)tret);
return 0;
}
//演示两个线程操作全局变量时相互干扰
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NLOOP 5000
int counter;
void *doit(void *);
int main(void)
{
pthread_t tidA, tidB;
pthread_create(&tidA, NULL, &doit, NULL);
pthread_create(&tidB, NULL, &doit, NULL);
pthread_join(tidA, NULL);
pthread_join(tidB, NULL);
return 0;
}
void *doit(void *vptr)
{
int i, val;
for(i=0; i<NLOOP; i++)
{
val = counter;
printf("%x: %d\n", (unsigned int)pthread_self(), val+1);
counter = val + 1;
}
return NULL;
}
//演示两个线程操作全局变量时相互干扰, 试用mutex解决
#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 tidA, tidB;
pthread_create(&tidA, NULL, &doit, NULL);
pthread_create(&tidB, NULL, &doit, NULL);
pthread_join(tidA, NULL);
pthread_join(tidB, NULL);
return 0;
}
void *doit(void *vptr)
{
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;
}
// pthread_cond,生产者、消费者模型
#include <stdlib.h>
#include <pthread.h>
#include <stdio.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);
// 线程调用pthread_cond_wait在一个Condition Variable上
// 阻塞等待,这个函数做以下三步操作:
// 1. 释放Mutex
// 2. 阻塞等待
// 3. 当被唤醒时,重新获得Mutex并返回
}
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);
// 线程可以调用pthread_cond_signal唤醒在
// 某个Condition Variable上等待的另一个线程
sleep(rand() % 5);
}
}
int main()
{
pthread_t pid, cid;
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
return 0;
}
//sem, 生产者、消费者模型
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#define NUM 5
sem_t blank_number, product_number;
int queue[NUM];
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void *consumer(void *p)
{
int n = 0;
for(;;)
{
sem_wait(&product_number);
printf("Consume -%d\n", queue[n]);
queue[n] = 0;
sem_post(&blank_number);
n = (n + 1) % NUM;
sleep(rand() % 5);
}
return NULL;
}
void *producer(void *arg)
{
int n = 0;
for(;;)
{
sem_wait(&blank_number);
queue[n] = rand() % 1000 + 1;
printf("Produce +%d\n", queue[n]);
sem_post(&product_number);
n = (n + 1) % NUM;
sleep(rand() % 5);
}
}
int main()
{
pthread_t pid, cid;
sem_init(&blank_number, 0, NUM);
sem_init(&product_number, 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_number);
sem_destroy(&product_number);
return 0;
}