原创 pthread_create(转)

2011-9-16 18:00 2899 9 9 分类: 工程师职场

/*************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<semaphore.h>
#include<pthread.h>

void thread(int a,int b)
{
int i;
for(i=0;i<3;i++)
printf("This is a pthread.\n");
printf("%d\n",a);
printf("%d\n",b);
}

int main(void)
{
pthread_t id;
int i,ret;
ret=pthread_create(&id,NULL,(void *)thread,5);

if(ret!=0)
{
printf ("Create pthread error!n");
exit (1);
}

for(i=0;i<3;i++)
printf("This is the main process.\n");
pthread_join(id,NULL);
return (0);
}
/*************************************************************/
bash-3.2$ gcc -pthread -o outfile.out a.c
/*************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<semaphore.h>
#include<pthread.h>
//#include <sys/sem.h>

sem_t s;
int data[2];

void write_data1(int *a)
{
    data[0]=*a;
    printf("write data1\n");
    sem_post(&s);
}

void write_data2(int *b)
{
    data[1]=*b;
    printf("write data2\n");
    sem_post(&s);
}

void operate_data1(void)
{
     sem_wait(&s);
     int product;
     product=data[0]*data[1];
     printf("乘法:%d*%d=%d\n",data[0],data[1],product);
}

void operate_data2(void)
{
     sem_wait(&s);
     int sum;
     sum=data[0]+data[1];
     printf("加法:%d+%d=%d\n",data[0],data[1],sum);
}
 
int main(void)
{
   sem_init(&s,0,0);
   pthread_t t1,t2,t3,t4;
   int a=11,b=22;


   pthread_create(&t1,NULL,(void *)write_data1,&a);
   pthread_create(&t2,NULL,(void *)write_data2,&b);
   pthread_create(&t3,NULL,(void *)operate_data1,NULL);
   pthread_create(&t4,NULL,(void *)operate_data2,NULL);

   pthread_join(t1,NULL);
   pthread_join(t2,NULL);
   pthread_join(t3,NULL);
   pthread_join(t4,NULL);
}

linux多线程小程序

刚接触linux的多线程编程,照着例子写了个小程序。

创建4个线程,2个线程往数组写整数,2个线程用数组里的数做加法、乘法,用信号量实现控制。

我的代码是如上

运行的结果是,
如果我线程的创建顺序是先创建写数据的线程,那没问题;
但是如果先创建做运算的线程的话,就有问题了。

当数没全写到数组里,就进行运算了。

我想了一下,是不是当第一个写数据的线程执行之后,信号量就有了一个资源,导致运算线程可以执行?
如果是这样的话,那程序应该怎么改?


你使用信号量的作用是做同步的
如果operate_data1或者 operate_data2线程先运行的话他们不会先去作运算的,
不会出现你说的那种“当数没全写到数组里,就进行运算了”的情况,
因为在他们运算之前调用了sem_wait(&s);

首先要有信号资源可用才可以去运算,而现在只有3种情况可以获得信号资源:
1、初始化信号量的时候是正值,显然你的不是 sem_init(&s,0,0);
2、void write_data1(int *a)线程运行后;
3、void write_data1(int *a)线程运行后;

只有以上这三种情况的任意一种发生了,两个operate_data中的一个才可能获得资源而运行。

要解决这种情况最简单的情况是把两个写数据操作放到一个线程中把两个操作数据放到一个线程中,这样就不会出现竞争的情况了。
或是在把两个写数据操作放到一个线程中,在操作线程中,在操作前sem_wait(&s);在操作后调用sem_post(&s);

/*************************************************************/
bash-3.2$ gcc -pthread -o outfile.out a.c
/*************************************************************/

1:传Struct结构的指针
typedef union {
   size_t arg_cnt;
   any_possible_arg_types;
} arg_type;

arg_type args[ARG_NUM + 1];
args[0].arg_cnt = ARG_NUM;
args[1].xxx = ...;

pthread_create (..., ..., thread_function, &args[0]);

2:传void*[]
你创建一个void*[],里面保存指向你的所有参数的指针,然后把这个void*[]传递给pthread_create就可以了么……  
多少个参数还不是随便你?给你个例子  
#include   <pthread.h>      
void*   route(void*   args)  
{  
                  int*   iptr   =   ((void**)args)[0];  
                  float*   fptr   =   ((void**)args)[1];  
                  char*   str   =   ((void**)args)[2];  
                  printf("integer:   %d\nfloat:   %f\nstring:   %s\n",   *iptr,   *fptr,   str);  
                  return   0;  
}      
int   main(void)  
{  
                  pthread_t   thr_id;  
                  int   ival   =   1;  
                  float   fval   =   10.0F;  
                  char   buf[]   =   "func";  
                  void*   arg[3]={&ival,   &fval,   buf};  
                  pthread_create(&thr_id,   NULL,   route,   arg);  
                  sleep(1);  
}

/*************************************************************/

#include <pthread.h>  包含头文件
pthread_create:

在 pthread_create 的第三个参数,是这么定义的:
    void *(* _start_routine) (void *)

1. 在第一个程序中,我们定义子线程运行函数地址
   void *hello(struct message *str)
   在 pthread_create中调用方式为:pthread_create(&thread_id, NULL, (void *)*hello, &test);
   或者是
   void *a;
   a=*hello;
   pthread_create(&thread_id,NULL,(void *)a,&test); 
    

2. 在第二个程序中,我们定义子线程运行 函数
   void thread(void)
   在 pthread_create 中调用方式为:ret=pthread_create(&id,NULL,(void *) thread,NULL);
    thread 本身就是表示 函数的地址了
    (void *) thread 还是转换为地址

关于 *hello() 和 hello() 的解释看下一篇

#include <pthread.h> //pthread_create
#include <stdio.h> //printf
struct message
{
    int i;
    int j;
};

void *hello(struct message *str)/*have the * */
{
    printf("the arg.i is %d\n",str->i);
    printf("the arg.j is %d\n",str->j);
}

int main(int argc, char *argv[])
{
    struct message test;
    pthread_t thread_id; //typedef unsigned long int pthread_t
    test.i=10;
    test.j=20;
    void *a;
    a=*hello;   //两种方法都可以实现 ,注释掉代码的也可以实现
    //pthread_create(&thread_id, NULL, (void *)*hello, &test);
    pthread_create(&thread_id, NULL, (void *)a, &test);
    printf("the new thread id is %u\n",thread_id);
    pthread_join(thread_id,NULL); //在主线程等待子线程结束
    return (0);
}

/*
void *(*__start_routine) (void *);
void *(* hello)
*/


#include <stdio.h>
#include <pthread.h>
void thread(void) 没有 *
{
     int i;
    for(i=0;i<3;i++)
    printf("%d This is a pthread\n",i);
}

int main(void)
{
    pthread_t id;
    int i,ret;
    ret=pthread_create(&id,NULL,(void *) thread,NULL);
    if(ret!=0)
    {
        printf ("Create pthread error!n");
        exit (1);
    }
    for(i=0;i<3;i++)
    printf("%d This is the main process.\n",i); 
    pthread_join(id,NULL)
    return (0);
}

 

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
9
关闭 站长推荐上一条 /3 下一条